{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 误差函数（损失函数）\n",
    "\n",
    "前面我们的预测函数为：y = w * x + b\n",
    "\n",
    "计算误差的方式为：y_predict - y\n",
    "\n",
    "这样计算出来的误差可能是正数，也可能是负数。\n",
    "\n",
    "比如，x[1]对应样本的误差为2， x[2]对应样本的误差为-2， 那么x[1]和x[2]的误差和为0，导致误差被抵消了。\n",
    "\n",
    "一般我们会通过取误差的平方来解决这个问题，也叫做平方误差，计算方式为：(y_predict - y)^2，好处是：\n",
    "1. 误差平方之后，都为正数，从而避免误差被抵消\n",
    "2. 平方会放大误差，使得模型对误差更敏感\n",
    "3. 平方误差是一个平滑函数，便于求导"
   ],
   "id": "f98c75ba8cc11455"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T08:42:51.658511Z",
     "start_time": "2025-07-16T08:42:51.647227Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ],
   "id": "e723b2e212ed15af",
   "outputs": [],
   "execution_count": 10
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T08:43:04.288440Z",
     "start_time": "2025-07-16T08:43:04.265872Z"
    }
   },
   "cell_type": "code",
   "source": [
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.randint(100) for i in x])\n",
    "print(x[:5])\n",
    "print(y[:5])"
   ],
   "id": "27af8fe0f1918734",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[41 37 83 23 43]\n",
      "[475 380 903 292 440]\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "预测函数为：\n",
    "$$ y_{\\text{predict}} = w \\cdot x + b $$\n",
    "\n",
    "误差函数为：\n",
    "$$ \\text{loss} = (y_{\\text{predict}} - y)^2 $$\n",
    "\n",
    "带入y_predict，得到最终的误差函数为：\n",
    "$$ \\text{loss} = (w \\cdot x + b - y)^2 $$\n",
    "\n",
    "$x$, $y$ 是样本，是已知的，$w$, $b$是未知的，不同的$x$, $y$对应的误差不同\n",
    "\n",
    "所以，误差函数就是一个$w$和$w$为自变量，$loss$为因变量的二元二次函数"
   ],
   "id": "38234e86d7faa452"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "二元二次函数可能忘记了，我们先忽略b，这样误差函数为：\n",
    "$$ \\text{loss} = (w \\cdot x - y)^2 $$\n",
    "\n",
    "就变成了一个一元二次函数。\n",
    "\n"
   ],
   "id": "330dbd1c18856715"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T08:43:09.872300Z",
     "start_time": "2025-07-16T08:43:09.861327Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 随机生成一些w的数据\n",
    "w = np.random.randint(-100, 100, 200)\n",
    "w.sort()\n",
    "print(w[:5])"
   ],
   "id": "4fcd913123b004cd",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-100  -98  -98  -97  -93]\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "然后带入到误差函数中",
   "id": "e52568e45a5e0e96"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T08:43:13.397122Z",
     "start_time": "2025-07-16T08:43:13.387257Z"
    }
   },
   "cell_type": "code",
   "source": [
    "loss = (w * x[1] - y[1]) ** 2\n",
    "print(loss[:5])"
   ],
   "id": "bfbec1bd964134ac",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[16646400 16048036 16048036 15752961 14600041]\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T08:43:16.577238Z",
     "start_time": "2025-07-16T08:43:16.330623Z"
    }
   },
   "cell_type": "code",
   "source": [
    "plt.plot(w, loss)\n",
    "plt.show()"
   ],
   "id": "996af75e17d7f551",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 14
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "所以误差函数：$$ \\text{loss} = (y_{\\text{predict}} - y)^2 $$\n",
    "就是是一条抛物线，纵坐标就是loss，因此纵坐标的最低点，就是误差最小的点。\n",
    "\n",
    "当然，预测函数y_predict如果不是线性函数，那么对应的误差函数可能就不是一条抛物线，而可能是一条复杂的曲线，但对于模型训练而言，训练的目的都是找到loss最小的点对应的w的值。"
   ],
   "id": "dfc330a616e6f32e"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "那么，如何找到最低点呢？这就需要梯度下降了。",
   "id": "f1f57e77b9dcd461"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 梯度下降\n",
    "\n",
    "什么是梯度？\n",
    "梯度，就是误差函数关于自变量w的导数。\n",
    "\n",
    "预测函数为：\n",
    "$y_{\\text{predict}} = w \\cdot x$\n",
    "\n",
    "误差函数为：\n",
    "$loss  = (y_{\\text{predict}} - y)^2 = (w \\cdot x - y)^2 $\n",
    "\n",
    "\n",
    "注意：$w$才是自变量，$x$和$y$这里要看做常量，比如某一个样本$x[i]$,$y[i]$ :\n",
    "\n",
    "$loss = (w \\cdot x[i] - y[i])^2$\n",
    "\n",
    "展开后为：\n",
    "\n",
    "$loss = x[i]^2 \\cdot w^2 - 2 \\cdot w \\cdot x[i] \\cdot y[i] + y[i]^2$\n",
    "\n",
    "那么，误差函数关于$w$的导数为：\n",
    "$dloss = x[i]^2 \\cdot 2 \\cdot w - 2 \\cdot x[i] \\cdot y[i] = 2 \\cdot x[i]^2 \\cdot w - 2 \\cdot x[i] \\cdot y[i]$\n",
    "\n",
    "这样，dloss就是在x[i]、x[i]这个样本上，误差函数对w的导数，w取不同的值，dloss的值就会不同。\n",
    "\n",
    "dloss如果等于0，那么w取这个值，误差就是最小的。"
   ],
   "id": "df92caf15e66b25c"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "画出w[10]位置的切线",
   "id": "58b8671462da03a3"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T08:51:20.066274Z",
     "start_time": "2025-07-16T08:51:19.814486Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 模拟出有序的w\n",
    "w = np.random.randint(-100, 100, 200)\n",
    "w.sort()\n",
    "loss = (w * x[1] - y[1]) ** 2\n",
    "\n",
    "# 计算 w[10] 处的导数值\n",
    "pos = 50\n",
    "dloss = 2 * w[pos] * x[1] ** 2 - 2 * x[1] * y[1]\n",
    "\n",
    "# 在 w[10] 附近构造切线\n",
    "tangent_line_length = 10\n",
    "tangent_line = dloss * (w - w[pos]) + loss[pos]\n",
    "\n",
    "# 画出原曲线和切线\n",
    "plt.xlim(-100,100)\n",
    "plt.ylim(0,1e7)\n",
    "plt.plot(w, loss)\n",
    "plt.plot(w, tangent_line, 'r--')\n",
    "plt.scatter(w[pos], loss[pos], color='green', zorder=5)\n",
    "\n",
    "plt.xlabel(\"w\")\n",
    "plt.ylabel(\"Loss\")\n",
    "plt.show()\n",
    "\n",
    "# 导数小于0，左高右低\n",
    "print(dloss)"
   ],
   "id": "77a9aaaf7c77069c",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-192400\n"
     ]
    }
   ],
   "execution_count": 28
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "画出w[110]位置的切线",
   "id": "aa50fd4fbc452d59"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T08:51:35.187405Z",
     "start_time": "2025-07-16T08:51:34.938345Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 模拟出有序的w\n",
    "w = np.random.randint(-100, 100, 200)\n",
    "w.sort()\n",
    "loss = (w * x[1] - y[1]) ** 2\n",
    "\n",
    "# 计算 w[110] 处的导数值\n",
    "pos = 110\n",
    "dloss = 2 * w[pos] * x[1] ** 2 - 2 * x[1] * y[1]\n",
    "\n",
    "# 在 w[10] 附近构造切线\n",
    "tangent_line_length = 10\n",
    "tangent_line = dloss * (w[pos - tangent_line_length:pos + tangent_line_length] - w[pos]) + loss[pos]\n",
    "\n",
    "# 画出原曲线和切线\n",
    "plt.plot(w, loss)\n",
    "plt.plot(w[pos - tangent_line_length:pos + tangent_line_length], tangent_line, 'r--')\n",
    "plt.scatter(w[pos], loss[pos], color='green', zorder=5)\n",
    "\n",
    "plt.xlabel(\"w\")\n",
    "plt.ylabel(\"Loss\")\n",
    "plt.show()\n",
    "\n",
    "# 导数大于0，左低右高\n",
    "print(dloss)"
   ],
   "id": "8d8c49e6e2da9d25",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-3478\n"
     ]
    }
   ],
   "execution_count": 29
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "所以，我们可以根据dloss的值来判断w的修改方向。\n",
    "\n",
    "dloss小于0，那就增加w\n",
    "dloss大于0，那就减少w\n",
    "\n",
    "这个过程就是梯度下降。\n",
    "\n",
    "因此，我们可以修改之前的模型训练代码，采用梯度下降的方式来进行训练。"
   ],
   "id": "90eb7f8e532ea942"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-16T09:10:27.519333Z",
     "start_time": "2025-07-16T09:10:27.185936Z"
    }
   },
   "cell_type": "code",
   "source": [
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.rand() * 100 for i in x])\n",
    "\n",
    "print(x[:5])\n",
    "print(y[:5])\n",
    "\n",
    "x = x / 100\n",
    "y = y / 100\n",
    "\n",
    "epoch = 1\n",
    "w = 0.1\n",
    "\n",
    "\n",
    "for _ in range(epoch):\n",
    "    for i in range(len(x)):\n",
    "        dloss = 2 * w * x[i] ** 2 - 2 * x[i] * y[i]\n",
    "        w = w - dloss  # 斜率大，调整幅度就大\n",
    "        print(w)\n",
    "\n",
    "y_predict = w * x\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, y_predict, color='r')\n",
    "plt.show()"
   ],
   "id": "17e077d363bdba36",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[74 93 30 58 28]\n",
      "[758.49047138 983.5673106  329.29300053 630.32341887 367.22878351]\n",
      "11.216138976483851\n",
      "10.108813752177703\n",
      "10.264985279968466\n",
      "10.670454842481533\n",
      "11.053808710833165\n",
      "10.826044854714187\n",
      "11.201855262566902\n",
      "10.9093906076989\n",
      "11.292052022360915\n",
      "10.449061618983489\n",
      "9.815781873374082\n",
      "9.853911873306233\n",
      "10.429198839591724\n",
      "10.91008819298848\n",
      "11.334370004883029\n",
      "10.22659378296014\n",
      "10.596706381972744\n",
      "11.28682076594938\n",
      "10.94792367519135\n",
      "10.806045195709334\n",
      "10.969647648547042\n",
      "10.67962663171846\n",
      "10.715302199685752\n",
      "11.045887027801985\n",
      "11.085801020846533\n",
      "10.55070601148868\n",
      "10.568045810419273\n",
      "10.480878477796546\n",
      "10.567291083333359\n",
      "10.663412748668351\n",
      "10.832547448221261\n",
      "11.189317261742687\n",
      "11.247808049869004\n",
      "11.19843176679916\n",
      "11.24555205926045\n",
      "11.417873047899132\n",
      "11.491357289055992\n",
      "10.215281812759514\n",
      "10.956557994265598\n",
      "10.983667816775402\n",
      "10.943791109417408\n",
      "11.145897589641331\n",
      "11.195670856232997\n",
      "11.210558958374854\n",
      "11.215787951628116\n",
      "10.31464013782082\n",
      "10.037345127946685\n",
      "10.1868563036297\n",
      "11.364544581095412\n",
      "11.556781513916519\n",
      "9.879155429834782\n",
      "10.673542609586297\n",
      "10.689728854903478\n",
      "10.897126862980821\n",
      "10.392888375444672\n",
      "10.404604754460127\n",
      "10.581123208667599\n",
      "11.279927394983897\n",
      "11.45914582454607\n",
      "11.712628089448055\n",
      "11.795616559027582\n",
      "10.458495424602404\n",
      "10.045173332173352\n",
      "11.330391175919907\n",
      "11.509374870960517\n",
      "9.574102977882905\n",
      "10.56541880742777\n",
      "10.33867110878462\n",
      "10.552673190346546\n",
      "10.712455396609037\n",
      "10.778143673080017\n",
      "11.206353735852872\n",
      "11.244767259765306\n",
      "10.67552978186074\n",
      "10.820856469693265\n",
      "10.83546359224702\n",
      "11.282097536838476\n",
      "11.132048021766673\n",
      "10.38313555880248\n",
      "10.94098888682613\n",
      "11.340410321768765\n",
      "10.367162842473201\n",
      "10.60555429969776\n",
      "9.944580233599803\n",
      "10.018835181230116\n",
      "10.297460480284538\n",
      "10.369532520373724\n",
      "10.540118346183059\n",
      "10.039010432836728\n",
      "10.218271552579992\n",
      "10.733651192285588\n",
      "10.582856262063231\n",
      "10.62747112318945\n",
      "10.613222023479729\n",
      "10.851575426413449\n",
      "11.062472382187565\n",
      "10.68071024007102\n",
      "11.146712028374743\n",
      "10.478821022136945\n",
      "10.452880825042019\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 31
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "上面的dloss值，就是梯度，所以叫做梯度下降。\n",
    "\n",
    "有了梯度下降，对于复杂的误差曲线，也能通过梯度下降的方式找到最低点。\n",
    "\n",
    "我们只需要基于预测函数，得到对应的误差函数，然后基于误差函数对w求导，就可以得到梯度，从而可以根据梯度调整w的值。"
   ],
   "id": "656cf1e2ac095676"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 导数、斜率、梯度\n",
    "### 导数\n",
    "导数的定义：对单变量函数 $ y = f(x) $，导数是函数在某个点的瞬时变化率：\n",
    "$$f'(x) = \\lim_{{\\Delta x \\to 0}} \\frac{f(x + \\Delta x) - f(x)}{\\Delta x}$$\n",
    "导数的几何意义：曲线在该点切线的斜率\n",
    "\n",
    "### 梯度\n",
    "梯度的定义：对多变量函数 $ f(x_1, x_2, \\dots, x_n) $（如 $ z = f(x, y) $），梯度是一个向量，是所有自变量方向上的偏导数构成的向量\n",
    "$$\n",
    "\\nabla f = \\left( \\frac{\\partial f}{\\partial x_1},  \\frac{\\partial f}{\\partial x_2},  \\dots,  \\frac{\\partial f}{\\partial x_n} \\right)\n",
    "$$\n",
    "函数 $ f(x, y) = x^2 + y^2 $ 的梯度是：\n",
    "  $$\n",
    "  \\nabla f = (2x, 2y)\n",
    "  $$"
   ],
   "id": "37856064b42272c0"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 常见函数的导数公式\n",
    "常数函数：$f(x) = c$的导数是0\n",
    "\n",
    "幂函数：$f(x) = x^n$的导数是$nx^{n-1}$\n",
    "\n",
    "指数函数：$f(x) = e^x$的导数是：$e^x$\n",
    "\n",
    "sin函数：$f(x) = sin(x)$的导数是：$cos(x)$\n",
    "\n",
    "cos函数：$f(x) = cos(x)$的导数是：$-sin(x)$\n",
    "\n",
    "sigmoid函数：$\\sigma(x) = \\frac{1}{1 + e^{-x}}$的导数是：$\\sigma(x) \\cdot (1 - \\sigma(x))$"
   ],
   "id": "ae8ad6f4ab2fa609"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 链式法则\n",
    "\n",
    "若 `y = f(g(x))`\n",
    "\n",
    "令 `u = g(x)`\n",
    "\n",
    "则 `y = f(u)`\n",
    "\n",
    "`dy/dx = (dy/du) * (du/dx)`\n",
    "\n",
    "\n",
    "例子:\n",
    "`f(x) = sin(x^2)`\n",
    "\n",
    "令`u = x^2`,\n",
    "\n",
    "则 `f = sin(u)`\n",
    "\n",
    "`df/dx = cos(u) * (du/dx) = cos(x^2) * 2x`\n"
   ],
   "id": "d5834d898d5b381f"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## SGD随机梯度下降\n",
    "SGD，是Stochastic Gradient Descent的缩写，即随机梯度下降，在每次迭代中，每次随机一个样本来更新w。"
   ],
   "id": "9c450d372bb7d14e"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.rand() * 100 for i in x])\n",
    "\n",
    "print(x[:5])\n",
    "print(y[:5])\n",
    "\n",
    "x = x / 100\n",
    "y = y / 100\n",
    "\n",
    "epoch = 200\n",
    "w = 0.1\n",
    "\n",
    "for _ in range(epoch):\n",
    "    # 随机选取一个样本（SGD 的核心）\n",
    "    i = np.random.randint(0, len(x))\n",
    "\n",
    "    dloss = 2 * w * x[i] ** 2 - 2 * x[i] * y[i]\n",
    "    w = w - dloss\n",
    "\n",
    "y_predict = w * x\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, y_predict, color='r')\n",
    "plt.show()"
   ],
   "id": "dc091c31303c813b"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 均方误差\n",
    "每次迭代，随机获取一部分样本来更新权重。\n",
    "\n",
    "对于一个批量而言，它的误差函数可以做如下推导。\n",
    "\n",
    "x[1]和y[1]这个样本的误差\n",
    "$loss1 = x[1]^2 \\cdot w^2 - 2 \\cdot w \\cdot x[1] \\cdot y[1] + y[1]^2$\n",
    "\n",
    "x[2]和y[2]这个样本的误差\n",
    "$loss2 = x[2]^2 \\cdot w^2 - 2 \\cdot w \\cdot x[2] \\cdot y[2] + y[2]^2$\n",
    "\n",
    "x[n]和y[n]这个样本的误差\n",
    "$lossn = x[n]^2 \\cdot w^2 - 2 \\cdot w \\cdot x[n] \\cdot y[n] + y[n]^2$\n",
    "\n",
    "假如这N个样本为一个批量，那么这N个样本的平均误差为，也叫做MES（Mean Squared Error）均方误差：\n",
    "$loss = (loss1 + loss2 + loss3 + ... + lossn) / n$\n",
    "\n",
    "那么这个批量的误差函数为：\n",
    "$loss = \\frac{w^2 \\cdot (x[1]^2 + x[2]^2 + ... + x[n]^2)}{n} - \\frac{2 \\cdot w \\cdot (x[1] \\cdot y[1] + x[2] \\cdot y[2] + ... + x[n] \\cdot y[n]}{n} + \\frac{y[1]^2 + y[2]^2 + ... + y[n]^2}{n}$\n",
    "\n",
    "那么，该误差函数关于w的导数为：\n",
    "\n",
    "$dloss = \\frac{2 \\cdot w \\cdot (x[1]^2 + x[2]^2 + ... + x[n]^2)}{n} - \\frac{2 \\cdot (x[1] \\cdot y[1] + x[2] \\cdot y[2] + ... + x[n] \\cdot y[n]}{n}$\n",
    "\n",
    "最终，该误差函数关于w的导数可以为：\n",
    "dloss = 2 * w * np.mean(x[i]^2) - 2 * np.mean(x[i] * y[i])"
   ],
   "id": "6e459b5b0a91ac2c"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## Mini-batch SGD",
   "id": "ffb14fd3a51f6a19"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "# 训练代码为\n",
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.randint(100) for i in x])\n",
    "\n",
    "print(x[:5])\n",
    "print(y[:5])\n",
    "\n",
    "x = x / 100\n",
    "y = y / 100\n",
    "\n",
    "epoch = 200\n",
    "w = 0.1\n",
    "batch_size = 10\n",
    "\n",
    "for _ in range(epoch):\n",
    "\n",
    "    # 随机打乱数据\n",
    "    # x_shuffled = x.copy()\n",
    "    # y_shuffled = y.copy()\n",
    "    # np.random.shuffle(x_shuffled)\n",
    "    # np.random.shuffle(y_shuffled)\n",
    "\n",
    "    indices = np.random.permutation(len(x))\n",
    "    x_shuffled = x[indices]\n",
    "    y_shuffled = y[indices]\n",
    "\n",
    "\n",
    "\n",
    "    # 按 batch_size 分批训练\n",
    "    for i in range(0, len(x), batch_size):\n",
    "        # 第i批\n",
    "        x_batch = x_shuffled[i:i + batch_size]\n",
    "        y_batch = y_shuffled[i:i + batch_size]\n",
    "\n",
    "        # 求批量的平均\n",
    "        x2_mean = np.mean(x_batch ** 2)\n",
    "        xy_mean = np.mean(x_batch * y_batch)\n",
    "\n",
    "        dloss = 2 * w * x2_mean - 2 * xy_mean\n",
    "\n",
    "        w = w - dloss\n",
    "\n",
    "y_predict = w * x\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, y_predict, color='r')\n",
    "plt.show()"
   ],
   "id": "55ebdc55e80d94e5"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "a = np.array([(1,1), (2,2), (3,3), (4,4), (5,5)])\n",
    "# 打乱a\n",
    "np.random.shuffle(a)\n",
    "print(a)"
   ],
   "id": "692ee4718dd6ba26"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "a = np.array([1, 2, 3, 4, 5])\n",
    "b = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "indices = np.random.permutation(len(a))\n",
    "print(indices)\n",
    "\n",
    "a_shuffled = a[indices]\n",
    "b_shuffled = b[indices]\n",
    "\n",
    "a_shuffled, b_shuffled"
   ],
   "id": "dc45714dc7121398"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "a = np.array([1, 2, 3, 4, 5])\n",
    "a1 = a[[2,3,4]]\n",
    "a1"
   ],
   "id": "6d6b691b82056564"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 扩展：多个局部最小值\n",
    "在梯度下降中，如果误差曲线存在多个局部最小值（如两个凹），判断当前是否是全局最低点通常需要结合以下方法：\n",
    "1. 梯度为零的条件\n",
    "    * 在只有一个凹的情况下，梯度为零且导数由负变正时，可以确定这是唯一的最低点\n",
    "    * 如果有多个凹，则梯度为零可能对应于多个局部最小值，此时无法仅凭梯度判断是否为全局最低点。\n",
    "2. 学习率与收敛性\n",
    "    * 梯度下降会通过不断更新参数 $ w $ 来逼近局部最小值。当梯度接近零时，算法会停止更新，认为达到了一个“最小点”。\n",
    "    * 如果初始参数 $ w $ 靠近某个局部最小值，梯度下降可能会收敛到该局部最小值，而不是全局最小值。\n",
    "3. 如何判断当前是全局最低点？\n",
    "    * 多次初始化\n",
    "        * 可以从不同的初始值出发运行梯度下降多次。如果每次都收敛到同一个点，则可能是全局最低点。\n",
    "        * 如果收敛到不同的点，则这些点可能是局部最小值，需要进一步分析。\n",
    "    * 优化策略改进\n",
    "        * 使用更高级的优化策略，如动量法 (Momentum)、自适应学习率优化 (Adam)，或者随机梯度下降 (SGD) 中加入噪声，可以帮助跳出局部最小值并寻找更低的点。\n",
    "        * 另外，可以尝试使用全局优化算法（如遗传算法、模拟退火等），它们更适合处理多凹的情况。\n"
   ],
   "id": "db2a67726e856b9"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 学习率\n",
    "学习率是梯度下降算法中的一个重要参数，它控制了每次更新参数 $ w $ 的幅度。\n",
    "\n",
    "学习率过大，会导致参数更新过大，可能错过最低点。\n",
    "\n",
    "学习率过小，会导致参数更新过小，导致模型训练速度变慢。"
   ],
   "id": "ecc76a0e32584e77"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "# 训练代码为\n",
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.randint(100) for i in x])\n",
    "\n",
    "print(x[:5])\n",
    "print(y[:5])\n",
    "\n",
    "x = x / 100\n",
    "y = y / 100\n",
    "\n",
    "# 调参 超参数\n",
    "epoch = 200\n",
    "batch_size = 10\n",
    "learning_rate = 0.1\n",
    "\n",
    "w = 0.1\n",
    "\n",
    "for _ in range(epoch):\n",
    "\n",
    "    # 随机打乱数据\n",
    "    # x_shuffled = x.copy()\n",
    "    # y_shuffled = y.copy()\n",
    "    # np.random.shuffle(x_shuffled)\n",
    "    # np.random.shuffle(y_shuffled)\n",
    "\n",
    "    indices = np.random.permutation(len(x))\n",
    "    x_shuffled = x[indices]\n",
    "    y_shuffled = y[indices]\n",
    "\n",
    "\n",
    "\n",
    "    # 按 batch_size 分批训练\n",
    "    for i in range(0, len(x), batch_size):\n",
    "        # 第i批\n",
    "        x_batch = x_shuffled[i:i + batch_size]\n",
    "        y_batch = y_shuffled[i:i + batch_size]\n",
    "\n",
    "        # 求批量的平均\n",
    "        x2_mean = np.mean(x_batch ** 2)\n",
    "        xy_mean = np.mean(x_batch * y_batch)\n",
    "\n",
    "        dloss = 2 * w * x2_mean - 2 * xy_mean\n",
    "\n",
    "        w = w - learning_rate * dloss\n",
    "\n",
    "y_predict = w * x\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, y_predict, color='r')\n",
    "plt.show()"
   ],
   "id": "5169ade2e4db2835"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 用pytorch来自动求导",
   "id": "9337ddfc89860342"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T13:00:29.864398Z",
     "start_time": "2025-06-18T13:00:29.858833Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(9., grad_fn=<AddBackward0>)\n",
      "tensor(5.)\n",
      "tensor(1.)\n",
      "tensor(10.)\n",
      "tensor(2.)\n",
      "tensor(15.)\n",
      "tensor(3.)\n"
     ]
    }
   ],
   "execution_count": 23,
   "source": [
    "import torch\n",
    "\n",
    "# 创建需要梯度的张量\n",
    "w = torch.tensor(2.0, requires_grad=True)\n",
    "b = torch.tensor(3.0, requires_grad=True)\n",
    "\n",
    "# 定义计算\n",
    "y = w ** 2 + w + b\n",
    "\n",
    "print(y)\n",
    "\n",
    "# 计算梯度\n",
    "y.backward(retain_graph=True)\n",
    "\n",
    "# 查看梯度\n",
    "print(w.grad)  # dy/dw = 2w + 1 = 5 (当x=2时)\n",
    "print(b.grad)  # dy/db = 1 (当b=3时)\n"
   ],
   "id": "df73b7833ebde2e"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T13:05:16.083751Z",
     "start_time": "2025-06-18T13:05:15.054280Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGdCAYAAACyzRGfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOfBJREFUeJzt3Qt4FOXZ//E7iRAOkgAiBhCBclABFU8gBKtiKlVRav9ttYpV66u2oBZ434onPMvB1yq1WqzUirYqtX1VFBUV0FI0iqJpaT0hB1EwWFAS5BAgmf91D0zcw8zuzO7saeb7ua40ZnZ2dxxp9sfz3M/9FBmGYQgAAECWFGfrjQAAABThAwAAZBXhAwAAZBXhAwAAZBXhAwAAZBXhAwAAZBXhAwAAZBXhAwAAZNU+kmeamppk/fr10q5dOykqKsr15QAAABe0Z+mWLVuka9euUlxcXFjhQ4NH9+7dc30ZAAAgBZ9++qkceOCBhRU+dMTDuviysrJcXw4AAHChvr7eHDywPscLKnxYUy0aPAgfAAAUFjclExScAgCArCJ8AACArCJ8AACArCJ8AACArCJ8AACArCJ8AACArCJ8AACArCJ8AACArMq7JmMAACB9jU2GLF39pXyxZYd0btdKBvfqKCXF+bFnGuEDAICAmf+vz+XmZ9+Tz+t2NB/rUt5Kbjyjv3x3YBfJNaZdAAAIWPD4+Z/eiQoeqrZuh3lcH881wgcAAAGaarn52ffEsHnMOqaP63m5RPgAACAglq7+Mm7EI5JGDn1cz8slwgcAAAHxxZYdvp6XKYQPAAAConO7Vr6elymsdgEAIADLaFVTkyHtW7eQzdt3iR1daFtR/s35uUL4AACgwJfRtm/Twvy+eZt96FBWh49f9dopJfV1Iu3bS64QPgAAKLBltEbM8UShw9K35S556dazvjlg5G7FCzUfAAAU+DLaRHQa5m8NS6KDR44x8gEAQACW0TqpuWlk3LG5734mnVduylnLdcIHAAAF4AuPy2OPW/tPmfP4tVHHHjrpPLl58I9F5tTktOU64QMAgALQ2cPy2DXTR8UdO+qKR+XLNuW2LddnjjkqqwGEmg8AAArA4F4dzZGKhJMkhmEbPI67fUFc8DBPz1HLdcIHAAAFoKS4yJwiUXYBZMr838iaO86IOrb0wP4y8Ib5UlufXy3XmXYBACCPmoWVJCgA1akRnSKJ7fNhN9px+C/mSH2rfUUaduddy3XCBwAAedIsrIuLAlB97Dv9K8zQ8vKy1XLD2cfGndNz0jzP15PNlutMuwAAkKNmYZ/HLJ21CkD18UR0dGToiYPigse/O3/LNnh0bNvCsVakaG/oyWbLdUY+AADIk2Zhxt4woI/r6IaGDNupmZL4sYO+//OU7CrZ02Y9di+XyacfKmMfe9f2evQ9dbQlm/0+CB8AAGSJBonZr61O2CwssgC0bvvOqKmZPhvXyoIHx8Y9p5fNaIcVJawi1XxC+AAAIEc1Hom8/F6tPPTamuYREruiUjnlFJEXX5SZNq+tIx4aPHQEZfj0RY7vEzvSkg2EDwAAcrQhXCJP16xPGDyGTlkgSyaNkJKYItTYlTPVKze5HmkZ2ns/yQbCBwAAebQhXJGIdGjbQr7culN+XDNfpr54b9w5ZlFpTGAwi1AjwoO+rwaPF5IUr+Ziqa3n1S6LFy+WM844Q7p27SpFRUXy9NNPRz1uGIbccMMN0qVLF2ndurVUVVXJihUr/LxmAAACuSFc0d7vZw3qZo52xAaP20/8adRqFqfAoCMtOtXy41lvyCPVnxT+UtutW7fKEUccIffdd5/t43fccYfcc889cv/998ubb74pbdu2lZEjR8qOHdlLVAAA5AsvIwoV5a3MJmKTzxwY95iGjllDvp80MDgt45VCXmp76qmnml92dNRjxowZcv3118vo0aPNY4888ogccMAB5gjJOeeck/4VAwBQQNyOKJx/3EFy84PXSvG18StXYnt3WEtoYwNDKlM8UuhLbVevXi21tbXmVIulvLxchgwZItXV1bbho6Ghwfyy1NfX+3lJAADkxYZw2kAsUSi49azD446d8+Mp8uZBh7sODF6meCJXxGRzR1vfO5xq8FA60hFJf7YeizV16lQzoFhf3bt39/OSAADI6w3hSpoa7ZfRGoZceO2FZkCwm5qxCwxup3h+MrSHPH7JceZqmWwHj7xY7XLNNdfIxIkTo0Y+CCAAgCDxsiFc8zLaJsNxCa3SlSyxy2rdTvGcOrBL1pbVZjx8VFRUmN83bNhgrnax6M+DBg2yfU5paan5BQBAkFlBYvZrq+XW5963DR7HXP5H2di2Q9Qy2tgltIk2pNPXTzTF41Qrkm2+Trv06tXLDCALFy6MGsnQVS9Dhw71860AACg4GiR6fLXeNnhoUakZPBJMoSTbkE67ojpN8eSquNSX8PH1119LTU2N+WUVmeo/r1271uz7MX78eLntttvkmWeekeXLl8tPfvITsyfI9773vUxcPwAAhaOoSKpGHx932G4n2tgplGQb0klEm3Sd4vFSK5L30y5vv/22nHTSSc0/W/UaF1xwgcyePVuuuuoqsxfIpZdeKps3b5bhw4fL/PnzpVWr7DUvAQAgk2x3mk02mlAU/3jvX86VxuISV1MjyVayRLZJT9RuPR94Dh8nnnii2c/DiY5+3HLLLeYXAABBk6jmwnZUYcYMkQkTPO9EWxITFNyuZLHOi60VySe+1nwAABBkyWou9PG40Q6b4CGG4XlqxO1Klmy2SS/YpbYAABTCFEtt/Q65dd6/HWsu4ramt5lm0dBh8To1kqxZWb6sZHGD8AEAgIcplmQ1F037d5aSLzfGPd7Y2CTR1R3iaWrEalamIywaNIw8XcniBtMuAADY8LpBm9IltC1igsdzB1eaq1l0l9m4aZkUm5Xl80oWN4qMRNWjOaB9QbTNel1dnZSVleX6cgAAIZ1q0bDgNXgkWkJrjUfM9CEkpLTaJo8+v5l2AQAghpcN2pxapMf27rD+pn/tU8tl+64mqShrJUf36CDLPvnKc4jI55UsbhA+AACI4XZZq13wuOT718vLfY9zfM6XW3fJhD/vadSpOaMpYv5BA8lNZ2Z/l9lso+YDAACPy1XLt2+xDR5z3/0sYfCI1RRT+KAran5mt2Q3YBj5AADAYVmr3dSL0zSLLqPtvHKTL+9/zZPLv1myG0CMfAAAEEM/9M88oou74PHFF839O6zQkm5k+GrbLnljlT9BJh8RPgAAsFlN8sw/vpn6GPHxUtvgob07ZP/943pxqHQDSLVPoyj5iPABAECC1S4aOv7wf7fYrmbR89z24vDOkKCi5gMAAIfVLra9O656trl1utOqmMjW6bV12+XW596Xr7bu9BQnhn6rkwQV4QMAgBgnXHG+rFnyStLeHYlWxUT24mjdssS2LbqT9m1ayHEF3McjGaZdAACIVFQk7ZMEDw0RXTxs4mZNxRxQ5m4qZtr3DwvsShfFyAcAABabnWh7TZqXdBM39+3Oo8c9YkdCKspK5aYzBwS+yRjhAwAAm9Ch5i9fLxUxu9pqIakGDysg2O1828XmHJ12iZ1yMfZ+v7iyp1T1r8iLPVqygY3lAADhZhc8Jk4U+dWvko5qOIWKyE3ktPA00SZ1RXsDzZJJIwo6eLCxHAAAyezeLdKiRfzxmL+TO23ipqFERzzs/gavxzRG6OPtWrVIuEmdIWI+rgGnkDeL84LwAQAIpIR1GA7TLLHBI52db61Q4bZZ2BcuN7MLAsIHACBwEtZhHNY1/glvvikyeLCn93AfFgxfNrMLEpbaAgACxarDiB2VaLNqhX3w0NEOj8HDS1jQZmGJ9nsp8rhsNwgIHwCAwHCqw9BOpQt///P4J6Sx5iLZJnJWqNBmYU77vRTZLNsNA8IHACAw7Oow7FqkH/zfT8rQKQvMUZJUJdpELjZUOO33UlHeyjwe9L4esVhqCwAIjLk16+QXc2rMfx73+p/ll3//o2On0sjlsOl8+Lvp82Fx34ys8LDUFgAQSlYdht1oR2yL9MjlsNqLI9UQELmJXLJQ4bRsN2wIHwCArMjG3/r1NW13oo3ZEM7vHhuECm8IHwCAjPMyNZGyli2lZNcu18EjrD028gEFpwCAnCx9ra3bYR5Pp+izmTYNiwken+7XzVXwCFuPjXxA+AAAZEyyFuRKH9fzUmbXrdQwpOsXn8qjFw+R9q1bOD81hD028gHhAwCQMW5bkOt5KYUOh+BhKS4uku8f1W3P6bFPD2mPjXxAzQcAIGPc1lJ4rrmwCx333y9y2WWONSb6lMjmEhV+15zANcIHACBj3NZSuK65qKsTad8+/nhEqnDa5t6a2bm4sqdU9a8IVI+NQsO0CwAgY9y2IHdVc6FDF0mCR6IaE+v9nv9XLcEjxwgfAICM8dKC3PM0yyefxO3NktEaE/iG8AEAyKi09jV58UXnotKDDspejQl8Rc0HACDjvLQgb2YXOlSCLcl8rzFBRhA+AABZ4akFuV3waGpyDiQxNSbawMwuohTtHXGhr0duMe0CAMgfP/yh8zRLkuDha40JMorwAQDIDxou/vpXT9MsvteYICuYdgEA5F6CTqWp7IabUo0JsobwAQDInSRFpenshss29/mLaRcAQP4EjzFjooJHxnfDRU4w8gEAyC5dtVJSknKnUj2msUUf16kVplIKDyMfAIDsjnYkCR6KTqXBRvgAAORummXhwrgRj+qVm+QFl1MqdCotTEy7AAAywlql8vV7H8h3zhyedLTDrrg0GTqVFibCBwDAd1aQqL62yv4Em+ChRaRuO3rQqbSwMe0CAPCVFSTsgsfA8U/I/OXro44lKi61Q6fSwkf4AAD4RoPEmv++XlZPHxX3WM9J82RraRszaOh5botLY9GptPAx7QIA8CRRx9GSkmL5mc1zNHjErlKxGoC5LRr9ydAecurALnQqDQDCBwDAtYQdRw/r6hg6YkUGDrdFoxo86FgaDL5PuzQ2NsrkyZOlV69e0rp1a+ndu7fceuutYnjcGAgAkF+cOo4uvn6kp+ARGzh0JEMDjNNYhh7XxykuDQ7fRz6mT58uM2fOlIcfflgGDBggb7/9tlx00UVSXl4uV155pd9vBwDIAqei0DU2tR2ql0PwsFulolMoOnKiwUYfj3wPikuDyfeRj9dff11Gjx4tp59+uvTs2VN+8IMfyCmnnCJLly71+60AAFliVxRqFzyqP97YvJolNiokChJaPKpFpBpMIlFcGky+j3wMGzZMHnjgAfnoo4+kX79+8o9//EOWLFkid911l99vBQBIk9vt6iNrNJxGO3Sa5ddbdsjoQd3MwBBbG1KRZDdaPa57tbi5HhQ238PH1VdfLfX19XLIIYdISUmJWQNy++23y3nnnWd7fkNDg/ll0ecCADLPy3b1Vo2GXfD49bAfy93Hnxd1XqpBQh+nqDT4fA8fTzzxhDz66KPy2GOPmTUfNTU1Mn78eOnatatccMEFcedPnTpVbr75Zr8vAwCQgFNHUWu7+tipjsH7t7QNHlZRqVMtB0ECdooMn5ehdO/e3Rz9GDduXPOx2267Tf70pz/JBx984GrkQ1+jrq5OysrK/Lw0AMDeqZbh0xc5NvaygsSSSSP2jFTYbQgXEzwUtRnhVl9fby4ucfP57fvIx7Zt26S4OLqOVadfmpqabM8vLS01vwAA2eFlu/qhfTrFPX7elbPktdZdXNdyABkPH2eccYZZ43HQQQeZ0y7vvvuuWWz605/+1O+3AgCkwE1H0W+vWiZD+9gUlhqGPOKySBXIWvj4zW9+YzYZGzt2rHzxxRdmrcdll10mN9xwg99vBQBIQbKOok6rWaydaKnlQN7VfGRzzggAkHrNhxaXumoatnu3zp9n6/JQoLx8frOrLQCEKHRUr9wk8/65Xs45trsZPKzJkkf+PNk+eOjfTwke8BkbywFASHt6tG/Twvxec+NI+yfl18A4AoTwAQAh7elRt22XrHYa7QAyiPABAAHmdUO4xsYmWbpyEytZkFGEDwAIMLcbwu08oEIWLXhHbo5pPubUbh1IBwWnABCWnh6G4dgifdqsBebUTGxQsdqt69QN4BdGPgAgwDq1LU26E616umZ93NSMslbE6NSNbhTHFAz8wMgHAARZkX3w+OWpVzYHD/Xl1p2u2q0DfmDkAwCCasUKqezXL+5wZOjwuy074AbhAwCCKMlOtJloyw64RfgAgBAEj2PH/VH+s2+H+FNF5IAyrQspkg318e3WrXN051pddgv4gZoPAAgK3cDTJnjMX75eNu7bobmVusX6+aYzB8hNZ/aPOhZ7ji63pdgUfiF8AEAQaOi49db444Zh9uiYOeYoc/Qikv6sx/VxN+cAfmFXWwAIYn2Hza927XaqK1YSdS91cw6Q7uc3NR8AELCiUqe9WTREDO29X8KXdHMOkC6mXQAgBMEDyCeMfABAoXE5zQLkK8IHAARwtIPaDeQzwgcAFGrwOO00keeeizusm8DpXizsTot8Rc0HAOSz7dudp1kcgge70yLfET4AwAc6zVG9cpPMrVlnftef06aho00b1/Ud+p464uG0O63Sx325NiANTLsAQJoyMs1hN9qxcKHIiBGOT9Eaj9gRD6fdaVlOi1xi5AMA0uD7NMdLLzlPsyQIHl52nWV3WuQaIx8AkKJk0xwaIfTx7/SvcLfSJM3eHW53nWV3WuQaIx8AkCIv0xwpBY8dOzz179DltDrd4xRz9Lg+zu60yDXCBwCkyJdpjpNPdp5mKdWt7t3T0RWtM1HsTot8RvgAgBRXtqzY8HV60xwaOhYt8rVbKbvTohBQ8wEAaa5scVK090Pfdpojgy3SNWBonQkdTpGvCB8A4HFli5uI4DjNkaUN4didFvmM8AEACVh7pNTW75Bb5/3bVfCQvSMecX0+2IkWMBE+AMBhQ7Y1G7fJ40vXmsHDrctP6i2VffaPn+ZwOc3ChnAIA8IHAKRQz+Gk7wHtoqc7PIx2sCEcwoLVLgCQoFOpV1ErW2yCx9oJ18jcdz+L2/+FDeEQJox8AAi9RJ1K3Ypa2fLZZyLdu8edM3TKgj3hYk5N1KiGrkzxtVMqkOcY+QAQesk6lXpa2VJSbBs8ek2a5ziqce+iFf51SgUKACMfAELLKu58Ic0pjeaVLYd1jX+PFR/L8L+sEcMmXFijGg+9tsbV+7AhHIKC8AEglNIpLtXA0LFtS7n+9EOlory1DJlzvxQfVhV/omHI0pWbko5qbN6+y9X7siEcgoLwASB0vDQLc5piuf2sgXtWoCRZzeJ2tKJ96xZSt32X7TUl7JQKFCBqPgCESrrFpVF7pNgFj6amqGW0bkcrLqrsZX5nQziEASMfAEIlneJSbSA24TsH7ykqtRMROiI7o3Zs20K+3Go/tWKNalw+oo8cXLFv3FSQbadUoMARPgCESjpFm0N7d3IVPNzWk8SOarAhHMKC8AEgVNIp2qzsu3/STqVe6knsRjXYEA5hQPgAECo6kqDNvbTHhtu6jzXTR9k/EBM8ktWTxK6SYVQDYUXBKYBQ0Q97HW1QRakGj379bPdmSVZPos/YtHWnGTx0dIPggbAifAAIHZ3m0BUrOu3hZJ/G3fbBQ0PHhx+mVU9CszCEHdMuAEIptrhzzcatcveCFeZoyGqX0yyp1pPQLAxhR/gAEFqxxZ0HV7SzbZH+7p2/kyP/+9K4ZbSxK1KS1ZPQLAzYg/ABIK84fbBn3CuvyHdHjIi/nsYmOTLi/e2W0Vq70+poin7X1S76jMgAQrMw4BuEDwB5I9kHe8YCikOL9OqPN8pgF8tord1prc6n+p1mYYCzIsNIMomZZfX19VJeXi51dXVSVlaW68sBkCVOH+xWLLA+2N0GlHSCx4DxT8jW0jZRr631IcOnL3JczWJNqSyZNMIMQjkbwQEK4POb1S4Aci5RfwzrmD7+/D/XmwElNgBYIw8aTFw7+WTb4NFz0rzm4BH52vcu+jjpMlp9XANHZD3J6EHdWFYLxCB8AMg5N/0x9PFJTy5PGlA0yCSloWPRItvg4fTaD72+OvnrsowWcIXwASDn3H5gb9mx2/XIgx0zmNiMdmhth13wiHztzdvsN4aLxTJaIEfhY926dTJmzBjZb7/9pHXr1nLYYYfJ22+/nYm3AhAAnfYtzXyQKSqy3RRu/vL1rsNP+9YtHLuiFu2tD2EZLZCD8PHVV19JZWWltGjRQl544QV577335Fe/+pV06NDB77cCEBQ+lr3bjjw4rGbpNWmeWc+hDcbcuKiy556Xi335vd9ZRgvkaKnt9OnTpXv37vLQQw81H+vVq5ffbwMgz3lZ7bFxa0Pa7+fYwMuhqDTyeY8vXSsVZa1kQ33i5mCXj+hrNiJjGS2QZ+HjmWeekZEjR8oPf/hD+dvf/ibdunWTsWPHyiWXXGJ7fkNDg/kVuVQHQGHzuhw23ToJ25EHh9GO2NoODRu19Q0yoaqfzFjwUdLmYLFt2VlGC+TBtMuqVatk5syZ0rdvX3nxxRfl5z//uVx55ZXy8MMP254/depUc12w9aWjJgAKv1+Hl+WwVlvyVD++deTB6gPiFDzmHH5KwqLSnp3a2G42F/faLKMF8q/JWMuWLeWYY46R119/vfmYho+33npLqqurXY18aAChyRhQmFMtXhpx2YUW5eaXUse2LWTyqAHmdMnRPTrIsk++ks2frJNTTz4i7txEocPy+CXHmUGC5mBAATYZ69Kli/Tv3z/q2KGHHipr1661Pb+0tNS8yMgvAMHu12G3HNbNNveqaO/XlLMOk7OO7CZ123fKCf/7igzt08k2eOjeLIlGVWJXqTCqAWSe7+FDV7p8+OGHUcc++ugj6dGjh99vBSDPuF2y6nSeBhAdFdFRiF+fM0gmVPWVirJSx2kQa7Sk+tqq+Nf66b3mMloND1qvoVilAgS04HTChAkybNgwmTJlivzoRz+SpUuXygMPPGB+AQg2t4Wjic6L3eZeV5jYTYPo9Mg/r5smq5+5x3aaRaOEFr1qcSibvQEh2Fhu3rx5cs0118iKFSvMZbYTJ050XO0Si43lgMKv+dDiUsNjzYdnLlezWLUc1vVRzwFkhpfPb99HPtSoUaPMLwDhYk1x6FRIsiWrabHr3XHVs7bHI6d4YkdVAOQGe7sA8ExHEKpXbpK5NevM75GbuTkVjtotWfVs332dm4Y5jISw1wqQfzIy8gEg3A3EMtKIK0GLdE8dTwHkHCMfADLSQMyvJatOO9GKYZirWRSrWIDCQvgA4DoE6IiHXSGpdUwfj5yCSVuCnWgzPsUDIGOYdgHgewMxu6JOzytNbEY7vmrVTo76xeMif3qnOVyw1wpQeAgfADLeQMzTRnNNTSIlJUl3orV6eGjIYBULUFiYdgGQ0QZinjaa09GOJMEjWZt2APmP8AHA1bLa2rrt0rFtS9d7pHiuE7GZZhk/6r8TbgrndjQGQH5h2gWAI7vpEjtOq0vc1Im0X/GelJRUpbQTLT08gMJE+ABgy5oucbN2xW6PFB3NeO3j/yR83prp9p2QzZ1oXbRpp4cHUJgIHwDiJJousXRs20ImjxogFWXxq0vcjJjYBo9Nm0Q6dhSt+shKm3YAOUHNB4A4yaZL1Jdbd5nBI7aBmFOBqWXaC/fYBw/d47LjNyMZ9PAAgouRDwC+LatNNmLiNM1iBg8b9PAAgonwAcC3ZbWJRkzsgod2Kk02gkEPDyB4CB8A4ujogi6b9VrwaTdikqio9LuMYAChRM0HANvRBi3o9LppW+xIiFPwqP54I1MnQIgRPoAQsxqIza1ZZ36P3BQulYJPa8SkyCF4aO+OQTe/KE1Nhr8b0AEoKEWG4VDplSP19fVSXl4udXV1UlZWluvLAQLL7X4rfmwIZ9c0zHFvFwAFycvnN+EDCCGnBmJWbEi2lNUxkNgEj9d6HC7nnTMl7rjb9wJQGLx8flNwCoRMsv1WYneMdTNi0qd0tyy45XueWqS7eS8AwUT4AELGzX4r1o6xsUtc7UZMnIpK3ezNkui9AAQX4QMIGT8biNkFjx+eO03e6j4wI9cEIBgIH0DI+NFA7P8tXyi/ev7ulEY70rkmAMFA+ADynOfVJklep7Z+h7kpnO7N4qR9mxbNy2Gt97JGJ5JNs7RpWSLbdja6uiZ2pwXCifABBGA5bCqvk8jmbbvkvAffjHovDT52waP3L+dKY7HuQ7tHscNS21jsTguEF03GgDzltDustjzX4/p4Oq/jhvVeDfvtL0P7dLId7bCCh8YHHVH5umG3q9dmd1ogvAgfQAEuh1X6eLIuocl2md0TGFpKeSv7QVB93urpo6T0y40J6zuscYuzBnUTNy4/qY8smTSC4AGEFOEDKPDlsOm+zpdbd0rdjt2edqIdOmWB7ShGVf8KcaOyTyemWoAQo+YDCNBy2FRfJ5ZTUakYhnxXxGwKZlcEqyMtqeyGCyBcGPkAArQcNtXXcbsTrUWDhjYFGz2om/ndGsVIdTdcAOFC+ADyUOTusHb0eBcXIwhuX6eirFQ3erINHr0mzTOnWdyOVqSyGy6AcGFjOSBPWatUlJHGhmyuXuewrrbP1eChz5lQ1Vd6dmrrqc+IX/1JABQGdrUFAiKTfT6aX8cmeNx5/Bi5d9g5ZrMxq+9HOu8PIPjqCR9AcPjd4bT5dXZskJKBA2xrO/ScNRu3yYwFH8UVjnodeQEQDvUePr9Z7QLkOau404/Q0vw6Dl1Itbbjxu07ZdThXWX49EWOfUb02TqSoqtemEoB4BXhAwjgyIfXaZYhY2fLhnadpGhvR9PxVX1d9xlJJRgBCDfCBxCwmg+rwDR21GLMM7+T7177l4SdSq1RjYdeW+Pq+lLtIwIg3AgfQJ5yChHWfit2NRdO7dST7UQbSZ+7ebvzjrfp9hEBAMIHUIB7uzjVXNi1U7cLHnahI1b71i2kbvsuOpUC8B1NxoAA7e0SOQ2ioSPV4KEuquxlfqdTKQC/ET6AAO3tYk2DJJtm0Z1sk3U9vXxEHzqVAsgIpl2AAO3totMgyUY7dDrlJ8f1kBkLV5hBw0gwqqEBw2kTOQBIFeEDyEPWniyedoctKpISm3Njp1m0mFSDh1330gqblTSp9hkBACeEDyAPu5Jau8PqqpZkoxN7Dsa/9quHVsqFZ17j+B51e0PHhKp+0rNTG0Y1AGQN4QPI0/1YrN1hY18ranRixw6R1q3jr2H5ernpmfdE6hMXrWrMmPPWWlkyaQShA0DWsLcLkIXeHOnsh+I4iuLQIl2Dh901JPL4JccxtQIga5/frHYBstSbQ+njep4XVs3F6EHdzO+OweOVV6SxscnxGhKhUymAbCJ8ADnuzRFJg0n1yk0yt2ad+T0uqCxcaB88dADzxBOTXoMTOpUCyCZqPoAc9+ZwXSviMM1iBg+P12ChUymAXGDkA8hxb47IWpHYUQtrHxfb4KHFpjElW15GMOhUCiBXCB+Az705knUOjR1lSFQr8tunpshqu26lGjpKSz1fQyQ6lQLIFaZdAJ947s2xl1OdhlOL9NjRDrfXYLm4sqdU9a+gpweA4I58TJs2TYqKimT8+PGZfisg56zeHF72Q7Gr07ALHnPf/Sxh8Eh2DToicv+Yo2TyGQO+WTUDAEEb+Xjrrbfkd7/7nRx++OGZfBsgr3jdDyWyTiPRhnCPe6jnYE8WAKEMH19//bWcd955MmvWLLntttsy9TZAXvKyH4pVp1F9bVXcY01SJL0nPWtbK+LnNQBAIKZdxo0bJ6effrpUVcX/Qo3U0NBgdkWL/ALCREOCXfDQ0Q4NHooVKQCCJCMjH3PmzJF33nnHnHZJZurUqXLzzTdn4jKA/OfQu8PaidZul1kAKHS+h49PP/1UfvGLX8jLL78srVoln6O+5pprZOLEic0/68hH9+7d/b4soCCCR9OMGfLmqDHya+o0AASY7xvLPf3003LWWWdJSUlJ87HGxkZzxUtxcbE5zRL5WCw2lkPg1daKdLEZycivPR4BwBMvn9++j3ycfPLJsnz58qhjF110kRxyyCEyadKkhMEDCDwXLdIBIOh8Dx/t2rWTgQMHRh1r27at7LfffnHHAQl78PjkE5GDDsrF1QBAztBeHci0Bx903omW4AEghLLSXv3VV1/NxtsA+YdpFgCIw8gHkM3g0dRE8AAQemwsh9DS3WQz0n68Xz+RFSvijxM6AMBE+EAozf/X5+Y29pG7yWoL88mnHyod2pamHkiYZgGApAgfCGXw0C3nY+OABpGxj70bdayLlw6jTkWlAIAo1HwgdFMtOuLhNhLU1u0wg4oGloShg+ABAK4RPhCq4DH7tdVRUy3JWPFBA4s+P45d6PjBDwgeAJAA0y4IbY2HWxoj9HlanNq8Rf3u3SItWticTOgAgGQIHwhtjYdXWoRqoqgUANLCtAsCzWuNRyK6+sU2eCxYQPAAAA8Y+UCg6VRJKlMtkTRuVG5fL0P7dIp/kNABAJ4RPhBozVMlaQSP1dNH2T42993PpPPKTf41JwOAkCB8INDMqZI02AWPE2+aJ2u2i8icGu+9QAAA1Hwg2HRUQsOBm3EJPe+35x4pj19ynLz0xQuyxiZ49Jq0N3h47QUCAGjGyAcCTadDdFRCw4EGELsKjYsre0pV/4pvpk8cVrMMnbJADJv6EX1NfYYWtn6nfwVTMACQBCMfCDydDpk55iipKI+egqkoK5UJVX3l8O7tvzno0Km0+uONCQtXI3uBAAASY+QDoQkgOiph7WK7ZuM2eXzpWrl7wZ7dZ+2mWCJXs7gtXE23wBUAwoCRD4SGTodoh9LSfYplxoKPpLZ+h3PwOOCAqGW0bgtX0y1wBYAwIHwg75uEVa/cJHNr1pnfbfdXSaPpmF3w0NqOxvWfeypc1eP6uJ4HAEiMaRcU1H4s6S5rtZqOOU2z9Jw0TyR2H5ckhatWINHHKTYFgOQY+UBe78cSW+SZ7rJWs97DJnjcdPKle4JHxHmuC1fLW5nH6fMBAO4w8oGC2o8lrWWtW7bI6CMPjDscGTqS1W7EFq7qeXQ4BQBvCB8ouP1YbLe4T8ahd0ds8CjaO5KRqHbDKlwFAKSG8IG848eyVh09sUYn7EY7hv58ttSWRW8UR+0GAGQHNR/IKxoaNm5pcHWu09SI1oMMn75I7rn+d7bBQ5fQ3jj2FGo3ACBHGPlAXq9usZNoasQqVHXaiXb+8vXyXWo3ACCnCB/ImcipEe04qo2/knXxSDQ1YhWq2gWPnlc9K0VFRVIRUahK7QYA5AbhAzkKG1vN9ua19e6mWCwVCfp8/Of8n0r1Y7Mdi0pTKlQFAPiO8IG8mlJJZPLph8qFlb3sp0Z0VMPmOXbLaNl/BQByi/CBjLPqMNJrjC7SqV2pY/BwEzos7L8CALlF+EDOGoZ5FRcaHHp39HIIHm56eAAAMo+ltshpwzA3bDdtswse48aZq1ms58S+hqKHBwDkHiMfyChr2/pUxYUG3ea+2CYz63FdQiti9uqIrS9JVKgKAMguwgcy6suvva1miRUVGhymWazgYaGHBwDkN8IHMqpj25auz7W2qp9Q1Vd6dmobHRrsgsfixSLHH2/7WvTwAID8RfhARlWUt/Zwrs3UyKefihx0UNLRDgBA4SB8IKN05EKLRRMVnbZv00Lu+/FRclzv/aKnRlxOswAACgurXUK+DLZ65SaZW7PO/K4/+03DhI5mOFVb6PFp3z9MKvt2Sh48tmwheABAADDyEcLW5lpL8dXWnXLrc9ErQrpkaEWIvp7dChTb93v0UZExY+JfhNABAIFRZBj59Vu9vr5eysvLpa6uTsrKynJ9OaHbLVZlalv52AAUtwKFaRYAKFhePr8Z+Qg4L63N9Rz9+L85YudXPyVcgWIXPAgdABBI1HwEWCqtzSN3fs2KqiqCBwCEDCMfAZZOa/Os7PxqFzqOPVZk6dLMvzcAIGcIHwGWToDI+M6vjHYAQGgRPgIslQCR8Z1fKSoFgNCj5iMEDb7clo1mfOdXu+DxyCMEDwAIGcJHgFkNvpSbKKEjHhlZZtvQ4DzNcv75/r4XACDvMe0ScIkafE0+/VDp0LY0szu/Ms0CAIhB+AiBnG0xbxc81q0T6do1s+8LAMhrhI+AsusmmrUt5j/4QOTQQ+OPM9oBACB8hKedutt9W5K2QE+GaRYAQBKEj5C0U6+t22EeT1RQmk5ocQwejY0ixdQ1AwC+wadCSNqpW8f0cT3POr965SaZW7NOfr1ghRlOYjuiWqFFg4mjWbOcV7MQPAAAmR75mDp1qjz55JPywQcfSOvWrWXYsGEyffp0Ofjgg/1+K3hspx65b0vd9p2udrpNutmcXejo0UNkzZqU/z0AAMHm+19L//a3v8m4cePkjTfekJdffll27dolp5xyimzdutXvt0KK7dQXvFdrO8rhebM5p9EOggcAIJsjH/Pnz4/6efbs2dK5c2dZtmyZfPvb3/b77QLPSwGo23bqT9Ws87TTbVy4OeEEkcWL40+gqBQAkA8Fp3V1deb3jh0ztFdIgHktALXaqWudhl0M0MjSsW1L2bR1Z0rXY4Ybu9GOW24RmTw5pdcEAIRPRqsBm5qaZPz48VJZWSkDBw60PaehoUHq6+ujvvDNqhUvBaCJ2qlbP48e5L3Blz63S1mpDO3TyX60g+ABAMiX8KG1H//6179kzpw5CQtUy8vLm7+6d+8uYed11YpdO3Xdp8Vu3xYtGvUaPFZPHyXV133H5mKYZgEAeFdkGJn5BLn88stl7ty5snjxYunVq5fjeTryoV8WHfnQAKLTNWVlZRJGuvz1x7PeSHre45cc59i11KlWRI8Pn77IcWom1prpo+IPvvmmyODBbv5VAAAhUV9fbw4iuPn89r3mQ7PMFVdcIU899ZS8+uqrCYOHKi0tNb/gfdVKovM0aNgFE2tqRqdudFQjMoBYP0+o6it9W+6S006wmSpjtAMAkKZ9MjHV8thjj5mjHu3atZPa2lrzuKYh7fuB5NyuWnF7ntudbiusYtbDHOpCCB4AgHycdily2NvjoYcekgsvvNDXYZugSjY1UrQ3KCyZNCKtnWltp2ZKbMqAtmwR2XfflN8HABB89bmedkF6kk2NKH08neARNzXz+usifSrjT+K/JwDAZ2y8kaeSrVpxtdGbWzpaVUnwAABkB7va5jENGLo0Nq0t7pNxapEOAECGED5y3BI9GadVK2mbOVNk7Nj44wQPAECGET5y3BI9JwHIbrRjzBiRP/4xa9cHAAgvwkcGWqLHjh1YLdF9r9VIJQDZLaNltAMAkEUUnOZBS/Rs7Alz+++vJngAAPIC4cMnOsUR+4EfST/i9XE9L9sBSFukj1j1dvTBl14ieAAAcoJplzxqie53ACpuapRV/zs67rzqjzdmpogVAAAXCB8+rVzJdEt0r8Hm1d9dIj03fx53Ts9J8+TXGQxAAAAkQ/jwaeXK0T06iGaSRCUd+rielylWsLHbifbYcX+U/+zbIeMBCACAZKj58Fi4aa1c0ccjLfvkq4TBQ+njel6mDC4zbIOHjnZo8CjaG5509AYAgFwhfPi0ciXnNR9FRVLSef+oQ+/v39MMHubDPu4JAwBAOph2SXPlilW4mdOaD5umYZW3vSjrtuyK2hMm243OAACwQ/iwkcoohk5l6JSGTsvYjZgU7Q0Avk55LFsmcswx8ccNQxb72OIdAAA/Me1iI5VRDP1g15GFRHyd8tDRjtjgcfXVzb07rD1hRg/qZn4neAAA8gUjHzZSHcXQKY1Lv91LZv19dVTxqX7uX3J8L/+mPNiJFgBQwBj5sBE5ihH7MZ+ocFNXwDywODp4WLlAj8eukPFs1iyCBwCg4BE+HOgohW4EpyMckfRnuw3iMr63i4aOSy+NPvbsswQPAEDBYdolAQ0Y3+lf4apwM5UVMq4x2gEACBDCRxJW4WYyGenzMXGiyN13xx8neAAAChjhwye+9/mwG+34+GOR3r09XhkAAPmF8OET3/p8NDSItLIJKIx2AAACgoLTHK+QiTJgQHzw6NWL4AEACBTCRw5XyMRNs7z3XvSxbdtEVq3K0NUCAJAbTLt4pEtlE61+8bJCxrRunciBB8YfZ7QDABBQhA8PtEmY9uqIXFLbxWbDNrcrZGyLSi+7TOT++327ZgAA8g3hw0Pw+Pmf3okrJtUCUz2edFrFTfBoarI/DgBAgFDz4YKv3Uv//nfnpmEEDwBACBA+XPDSvTQhDRff/nb0sYcfpr4DABAqTLu44Ev3UlqkAwBgYuTDhU77lqZ+3j33EDwAAIjAyIcbRorn2YWOd94ROfJIP64KAICCRPhwYePWBm/n6ahGsc2gEqMdAACEZ9pFV6JUr9wkc2vWmd9drUxJZdO4u+4ieAAAEPaRD7fNwdLdNG5on07xD27eLFJenu6/AgAAgVEcluZgsUtlreZg+ni6m8aV7mqQ6mur7Ec7CB4AAIQnfPjZHMxp07j7598lH9z1/6JPvukmplkAAAjjtIuX5mBu9mKJ3TRu9JE2G8I1NtrXfAAAgOCHD1+ag8UwN41rtUOkDzvRAgCQikD/Fd3TKhW37r5b5MCY4PHXvxI8AABwKdAjH25Xqeh5rtCpFACAtAV65CPZKhWlj+t5Ca1bFx88JkwgeAAAkIJAh49Eq1T0Zz2etM/HX/4SP83y+ed7mokBAADPAj3t4rRKRWs8dKol6YjHqaeKzJ8ffYzRDgAA0hKK8NG8SsXFclrThg0iFRXRx/7v/0S+//2MXBsAAGESmvDh2iOPiFxwwTc/a63Hjh0iLVvm8qoAAAiMwNd8uKbTKQMGRAePW24RaWoieAAA4CNGPtSqVSK9e0cfe/99kUMOydUVAQAQWIx83HlndPDo0WNPi3SCBwAAGRHekY/du0U6dhTZsuWbY/ffL3LZZbm8KgAAAi+c4aOmRuTII6OPffaZSLduuboiAABCI3zTLv/zP9HBY/jwPUWlBA8AALIiXCMf2rtDe3hY6N0BAEBwRj7uu+8+6dmzp7Rq1UqGDBkiS5culZyqr48OHl9+SfAAACAo4ePPf/6zTJw4UW688UZ555135IgjjpCRI0fKF198ITlTVibyxBMiDz+8p6dHhw65uxYAAEKsyDD836xERzqOPfZYuffee82fm5qapHv37nLFFVfI1VdfnfC59fX1Ul5eLnV1dVKmgQEAAOQ9L5/fvo987Ny5U5YtWyZVVVXfvElxsflzdXV13PkNDQ3mBUd+AQCA4PI9fGzcuFEaGxvlgAMOiDquP9fW1sadP3XqVDMpWV86QgIAAIIr50ttr7nmGnOIxvr69NNPc31JAACgkJbadurUSUpKSmRD5MoSc5f6DVIRu029iJSWlppfAAAgHHwf+WjZsqUcffTRsnDhwuZjWnCqPw8dOtTvtwMAAAUmI03GdJntBRdcIMccc4wMHjxYZsyYIVu3bpWLLrooE28HAADCHj7OPvts+c9//iM33HCDWWQ6aNAgmT9/flwRKgAACJ+M9PlIB30+AAAoPDnt8wEAAJAI4QMAAGQV4QMAAGQV4QMAAGQV4QMAABT+Utt0WItv2GAOAIDCYX1uu1lEm3fhY8uWLeZ3NpgDAKDw6Oe4LrktqD4f2op9/fr10q5dOykqKkorgWmA0Y3q6BeSedzv7OJ+Zxf3O7u434V5vzVOaPDo2rWrFBcXF9bIh17wgQce6Nvr6Y3kD2/2cL+zi/udXdzv7OJ+F979TjbiYaHgFAAAZBXhAwAAZFVgw0dpaanceOON5ndkHvc7u7jf2cX9zi7ud/Dvd94VnAIAgGAL7MgHAADIT4QPAACQVYQPAACQVYQPAACQVQUdPu677z7p2bOntGrVSoYMGSJLly5NeP5f/vIXOeSQQ8zzDzvsMHn++eezdq1B4OV+z5o1S44//njp0KGD+VVVVZX0vw/S+/NtmTNnjtkd+Hvf+17GrzHM93vz5s0ybtw46dKli7lKoF+/fvxOyeD9njFjhhx88MHSunVrsxvnhAkTZMeOHVm73kK2ePFiOeOMM8zOo/q74emnn076nFdffVWOOuoo8892nz59ZPbs2f5elFGg5syZY7Rs2dL4wx/+YPz73/82LrnkEqN9+/bGhg0bbM9/7bXXjJKSEuOOO+4w3nvvPeP66683WrRoYSxfvjzr1x6G+33uueca9913n/Huu+8a77//vnHhhRca5eXlxmeffZb1aw/D/basXr3a6Natm3H88ccbo0ePztr1hu1+NzQ0GMccc4xx2mmnGUuWLDHv+6uvvmrU1NRk/drDcL8fffRRo7S01Pyu9/rFF180unTpYkyYMCHr116Inn/+eeO6664znnzySV3dajz11FMJz1+1apXRpk0bY+LEiebn5W9+8xvz83P+/Pm+XVPBho/Bgwcb48aNa/65sbHR6Nq1qzF16lTb83/0ox8Zp59+etSxIUOGGJdddlnGrzUIvN7vWLt37zbatWtnPPzwwxm8ynDfb73Hw4YNM37/+98bF1xwAeEjg/d75syZxre+9S1j586dWbzK8N5vPXfEiBFRx/SDsbKyMuPXGjTiInxcddVVxoABA6KOnX322cbIkSN9u46CnHbZuXOnLFu2zBzKj9wTRn+urq62fY4ejzxfjRw50vF8pHe/Y23btk127dolHTt2zOCVhvt+33LLLdK5c2e5+OKLs3Sl4b3fzzzzjAwdOtScdjnggANk4MCBMmXKFGlsbMzilYfnfg8bNsx8jjU1s2rVKnOK67TTTsvadYdJdRY+L/NuYzk3Nm7caP6fXP9PH0l//uCDD2yfU1tba3u+Hof/9zvWpEmTzPnG2D/Q8Od+L1myRB588EGpqanJ0lWG+37rh9+iRYvkvPPOMz8EP/74Yxk7dqwZsLVTJPy93+eee675vOHDh5s7p+7evVt+9rOfybXXXpulqw6XWofPS939dvv27WbdTboKcuQDhWXatGlmEeRTTz1lFpfBX7qF9fnnn28W+Xbq1CnXlxMKTU1N5ijTAw88IEcffbScffbZct1118n999+f60sLJC1+1JGl3/72t/LOO+/Ik08+Kc8995zceuutub40hGnkQ3/BlpSUyIYNG6KO688VFRW2z9HjXs5Hevfbcuedd5rhY8GCBXL44Ydn+ErDeb9Xrlwpa9asMavZIz8c1T777CMffvih9O7dOwtXHp4/37rCpUWLFubzLIceeqj5N0adVmjZsmXGrztM93vy5MlmwP6v//ov82ddrbh161a59NJLzdCn0zbwj9PnZVlZmS+jHqog/4vp/7H1bxsLFy6M+mWrP+s8rB09Hnm+evnllx3PR3r3W91xxx3m30zmz58vxxxzTJauNnz3W5ePL1++3Jxysb7OPPNMOemkk8x/1mWJ8PfPd2VlpTnVYoU89dFHH5mhhODh//3WmrHYgGEFP7Yn819WPi+NAl6qpUuvZs+ebS4FuvTSS82lWrW1tebj559/vnH11VdHLbXdZ599jDvvvNNc+nnjjTey1DaD93vatGnmUrq//vWvxueff978tWXLlhz+WwT3fsditUtm7/fatWvN1VuXX3658eGHHxrz5s0zOnfubNx22205/LcI7v3W39d6vx9//HFzGehLL71k9O7d21zFiOT09662PdAv/di/6667zH/+5JNPzMf1Xus9j11q+8tf/tL8vNS2CSy1jaBrjw866CDzQ06Xbr3xxhvNj51wwgnmL+BITzzxhNGvXz/zfF1G9Nxzz+XgqsNxv3v06GH+IY/90l8iyMyf70iEj8zf79dff91crq8forrs9vbbbzeXO8P/+71r1y7jpptuMgNHq1atjO7duxtjx441vvrqqxxdfWF55ZVXbH8fW/dYv+s9j33OoEGDzP8++uf7oYce8vWaivR//BtHAQAACGDNBwAAKFyEDwAAkFWEDwAAkFWEDwAAkFWEDwAAkFWEDwAAkFWEDwAAkFWEDwAAkFWEDwAAkFWEDwAAkFWEDwAAkFWEDwAAINn0/wHPk1Ijh0LPSQAAAABJRU5ErkJggg=="
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最终拟合的权重 w: 10.688233375549316\n"
     ]
    }
   ],
   "execution_count": 26,
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 数据准备\n",
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.rand() * 100 for i in x])\n",
    "\n",
    "# 将数据归一化到 [0,1] 范围内\n",
    "x = x / 100.0\n",
    "y = y / 100.0\n",
    "\n",
    "# 将 NumPy 数组转换为 PyTorch 张量\n",
    "x_tensor = torch.tensor(x, dtype=torch.float32)\n",
    "y_tensor = torch.tensor(y, dtype=torch.float32)\n",
    "\n",
    "# 初始化模型参数 w 为可学习的 Parameter，设置 requires_grad=True，表示w参数需要求导，需要计算梯度\n",
    "w = torch.nn.Parameter(torch.tensor(0.1, dtype=torch.float32), requires_grad=True)\n",
    "\n",
    "# 定义优化器 (SGD - 随机梯度下降)\n",
    "optimizer = torch.optim.SGD([w], lr=0.01)  # learning_rate = 0.01   # w = w - lr*w.grad\n",
    "\n",
    "# 训练循环\n",
    "epochs = 200\n",
    "for _ in range(epochs):\n",
    "    # 遍历每个样本\n",
    "    for i in range(len(x_tensor)):\n",
    "\n",
    "        # 前向传播: 计算预测值\n",
    "        y_predict = w * x_tensor[i]\n",
    "\n",
    "        # 损失函数: 平方误差\n",
    "        loss = (y_predict - y_tensor[i]) ** 2\n",
    "\n",
    "        loss.backward()     # 反向传播\n",
    "        optimizer.step()  # 更新参数w的值\n",
    "        optimizer.zero_grad()  # 清除w之前的梯度\n",
    "\n",
    "# 最终预测结果\n",
    "final_prediction = w.data.item() * x_tensor\n",
    "\n",
    "# 绘图\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, final_prediction.numpy(), color='r')\n",
    "plt.show()\n",
    "\n",
    "# 输出最终的权重值\n",
    "print(f'最终拟合的权重 w: {w.data.item()}')\n"
   ],
   "id": "e72a0ee9dc4588c2"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "接下来，我们来考虑偏置bias",
   "id": "637395bdf2b9c7b9"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T13:05:51.074929Z",
     "start_time": "2025-06-18T13:05:49.598741Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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59R9+/bJNddcIzfeeGNIVx0t1Tb3S939dteuXUbdTabycuQD+WXSpElGEeQLL7xgFJfBX7qF9U9+8hOjyLdjx47ZvpxIaGhoMEaZHnroITnllFPk0ksvld/+9rfy4IMPZvvSCpIWP+rI0gMPPCCLFy+W559/Xl555RW54447sn1piNLIh/4F27RpU9m0aVOj4/q8rKzM8nf0uJvzkdn3bbrnnnuM8DF79mw58cQTA77SaH7fq1evlnXr1hnV7PE3R9WsWTNZsWKFdO/ePYQrj86fb13h0rx5c+P3TD179jT+jVGnFVq0aBH4dUfp+544caIRsH/+858bz3W14o4dO2TUqFFG6NNpG/jH7n5ZUlLiy6iHysv/xfT/2PpvG3PmzGn0l60+13lYK3o8/nz1+uuv256PzL5vdffddxv/ZjJr1izp27dvSFcbve9bl48vXbrUmHIxHxdeeKEMGjTI+Gddlgh//3wPHDjQmGoxQ55auXKlEUoIHv5/31ozlhgwzODH9mT+C+V+GcvjpVq69OrRRx81lgKNGjXKWKpVXV1tvP6Tn/wkNn78+EZLbZs1axa75557jKWft9xyC0ttA/y+J02aZCyle+6552JffPHFgcf27duz+N+icL/vRKx2Cfb7/vTTT43VW2PGjImtWLEiNnPmzNihhx4au/POO7P436Jwv2/9+1q/76eeespYBvrXv/411r17d2MVI9LTv3e17YE+9LZ/7733Gv+8fv1643X9rvU7T1xq+5vf/Ma4X2rbBJbaxtG1x127djVucrp0a+HChQdeO/vss42/gOM9++yzsWOPPdY4X5cRvfLKK1m46mh830ceeaTxhzzxoX+JIJg/3/EIH8F/3++8846xXF9vorrs9ne/+52x3Bn+f9979+6N3XrrrUbgaNmyZaxLly6xa6+9NrZ169YsXX1+mTt3ruXfx+Z3rD/1O0/8nT59+hj/++if70ceecTXayrS//BvHAUAAKAAaz4AAED+InwAAIBQET4AAECoCB8AACBUhA8AABAqwgcAAAgV4QMAAISK8AEAAEJF+AAAAKEifAAAgFARPgAAQKgIHwAAQML0/wF+m3wCnynVIwAAAABJRU5ErkJggg=="
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最终拟合的权重 w: 12.260981559753418\n"
     ]
    }
   ],
   "execution_count": 27,
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 数据准备\n",
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.rand() * 100 for i in x])\n",
    "y = y + 100\n",
    "\n",
    "# 将数据归一化到 [0,1] 范围内\n",
    "x = x / 100.0\n",
    "y = y / 100.0\n",
    "\n",
    "# 将 NumPy 数组转换为 PyTorch 张量\n",
    "x_tensor = torch.tensor(x, dtype=torch.float32)\n",
    "y_tensor = torch.tensor(y, dtype=torch.float32)\n",
    "\n",
    "# 初始化模型参数 w 为可学习的 Parameter，设置 requires_grad=True，表示w参数需要求导，需要计算梯度\n",
    "w = torch.nn.Parameter(torch.tensor(0.1, dtype=torch.float32), requires_grad=True)\n",
    "\n",
    "# 定义优化器 (SGD - 随机梯度下降)\n",
    "optimizer = torch.optim.SGD([w], lr=0.01)  # learning_rate = 0.01   # w = w - lr*w.grad\n",
    "\n",
    "# 训练循环\n",
    "epochs = 200\n",
    "for _ in range(epochs):\n",
    "    # 遍历每个样本\n",
    "    for i in range(len(x_tensor)):\n",
    "\n",
    "        # 前向传播: 计算预测值\n",
    "        y_predict = w * x_tensor[i]\n",
    "\n",
    "        # 损失函数: 平方误差\n",
    "        loss = (y_predict - y_tensor[i]) ** 2\n",
    "\n",
    "        loss.backward()     # 反向传播\n",
    "        optimizer.step()  # 更新参数w的值\n",
    "        optimizer.zero_grad()  # 清除w之前的梯度\n",
    "\n",
    "# 最终预测结果\n",
    "final_prediction = w.data.item() * x_tensor\n",
    "\n",
    "# 绘图\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, final_prediction.numpy(), color='r')\n",
    "plt.show()\n",
    "\n",
    "# 输出最终的权重值\n",
    "print(f'最终拟合的权重 w: {w.data.item()}')\n"
   ],
   "id": "5c4d86012eb6f86f"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "不管怎么选了，都不能拟合前面一部分数据，导致直线方向不对",
   "id": "fd5994816a4ae2af"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T13:08:39.459871Z",
     "start_time": "2025-06-18T13:08:38.215440Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGdCAYAAACyzRGfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAPVJJREFUeJzt3QucVfP+//HPnumeikqmFI0uFFG51IQjKZVkjrvcO8Tx06E6Pyp/uYUUP/pRPx2dQ+e4lBxSipByiEmoKKGLIjGY0kxKU83s/+Ozau32Za29155Z+7pez8dj/8Zee+2919k/Zr/n+/18P1+f3+/3CwAAQJLkJOuNAAAAFOEDAAAkFeEDAAAkFeEDAAAkFeEDAAAkFeEDAAAkFeEDAAAkFeEDAAAkVQ1JM5WVlfLDDz9IgwYNxOfzpfpyAACAA9qzdPv27dKiRQvJycnJrPChwaNVq1apvgwAAFAFmzZtkpYtW2ZW+NARD/PiGzZsmOrLAQAADpSVlRmDB+b3eEaFD3OqRYMH4QMAgMzipGSCglMAAJBUhA8AAJBUhA8AAJBUhA8AAJBUhA8AAJBUhA8AAJBUhA8AAJBUhA8AAJBUaddkLFkqKv2ydMNW+Xn7LmnWoI6ckt9YcnPYSwYAgESr4cWwsbFkh0xf+p0Ul5UHHm/eqI7cPbCj9DuueUqvEwCAbOeJ8DF/1Y9y72ur5cfSXbbnFJfukpueWyZPXtmVAAIAQALleCF4aKiIFjyUf/9PDSk6SgIAABIjq8OHhggNE06jhJ6nIUWnZwAAQGJkdfjQEBFrxMOK1oUAAIDEyOrwUdUQsfan36Ro/RamXwAASICsDh+6hLYqJi1aJ4OmLpHTxi80akYAAIB7sjp8aO8OXUJb1e4d5goYAggAAO7J6vChTcO0d4eqSgBhBQwAAO7L6vChtGeH9u7IaxQ6BaMjIsN7t5ehZ7aJ+nxWwAAA4C5PNBnTANKnY55lO/XZKzY7eg1WwAAA4A5PhA+lQaOgTZOI400Pqu3o+U7PAwAAHp92CfD7RSZMEBkyRGTv3qDjTp+fqAsDAMBbvBM+yspERo4U+fvfRWrWFPnkE+NwyY4Dm8tF4/Q8AAAQnXfCR6NGIuecc+D+ySeLDB7suBdIVXuGAAAAr4YPNW+eyOzZB+5PmyYFbZtKl8pS26W4vv0rY7RAFQAAVJ+3woc67zyR7dtDDs16+Aq55+0pEQHEvK+9QrRgFQAAVJ/3woc66KB9BajdugUOXbNsrmwYf67UqDhQjKq9QbRHiC7VBQAA7vDMUltLS5bsuxUUBA6te+SPsvR/pkpF4fmBXiAAAMA9Pr9fhwDSR1lZmTRq1EhKS0ulYcOGyXlT/QhyLAaB0uujAQAgbcXz/e3NaZdwPt+BPiDhx59/PlVXBQBAViJ8BLvtNpGPPgo9duWV+0IIAABwBeEjiO5cW9Skjcxe/n3kgxpAtrK5HAAA1eXtgtMg81f9KPe+ttrYwVbdOnKu/GPeBDlr1XsHTmqyf28YakEAAKgyRj72B4+bnlsWCB6m6wfcLm1uC2pKZmIaBgCA5IWP9957TwYOHCgtWrQQn88nr776asjjunjmrrvukubNm0vdunWld+/esnbtWknnqRYd8bAay9BjlTm5UvDgAusAMnFiMi4RAABvh48dO3bICSecIJMnT7Z8fMKECfL444/LlClT5KOPPpL69etL3759Zdeu0FGFdLF0w9aIEY/wAKKPF60rEVm0KPTB4cMZBQEAINE1H/379zduVnTUY+LEiXLnnXdKYWGhcexf//qXHHbYYcYIyWWXXSbp5uftu5yf17PnvnqP8MCh97dsEWnM/i8AACS15mPDhg1SXFxsTLWYtOFIt27dpKioyPI55eXlRmOS4FsyVWlXWw0gXbuGnqDFqIyCAACQ3PChwUPpSEcwvW8+Fm7cuHFGQDFvrVq1kmTSFuq6a2202NC4fk0pLtslReu3GDUihk8/Fdl7YB+YAJsAYizjXb9FZq/YHPo6AAB4TMqX2o4ePVpGjBgRuK8jH8kMILp3i+5aq6tdNDZYRYKtO/bI8BdXGP+sQUXPNzaby821n4Z59NF9NSEWy3gjXgcAAA9xdeQjLy/P+PnTTz+FHNf75mPhateubfSAD74lmwYA3b1Wd7GNpbh0lxFUNFAEaAAJL0bVQOXz2S7jtXwdAAA8wNXwkZ+fb4SMd955J2QkQ1e9FATtHJuONIAsHtlLpg/pLo9dcoI0rl/L8jxzZERHMkKmTsxi1PDX7dRCGv1e5vx1AADIcnGHj99++01WrFhh3MwiU/3n7777zuj7MWzYMLn//vtlzpw5snLlSrn66quNniB//OMfJd3pFExBmyaS16iubN2xO+byW12mG/mgX+TEE0MOrXj8ctk4/tz4XgcAgCwVd83HJ598ImeeeWbgvlmvcc0118i0adPk9ttvN3qB3HDDDbJt2zY57bTTZP78+VKnjrNVJRm3/NbKJ5+IVFSI1Aj9eDWAtB45t8rvBwCAJ0c+evbsafTzCL9p8FA6+nHfffcZq1u0sdiCBQukffv2kkmqtPw2XG7uvsZkYTSA3P6faVV6PwAAsgF7u1Rh+a0e18f1vFivo63ZL738oZDj/7Xk30YIcfo6AABkE8JHlOW3KjyAmPf1cT3PyessbXWc5FtMt2wYf648UHBozNcBACCbED7iXH6r9/W40/4cwa+j9R6lteuHPN7rzBPojAoA8BSfXws20oguzdVOp6WlpSnp+RFOl8HqahQtCtXaDJ0iqcpIRcjr1KspBUeHdoE1OPx/hVvXBABAKr6/U97hNFOW37r+OnadUW+/XWT8eNvXoVsqACDTMe2SShpA3ngj9NiECbbTMNXplsreMgCAdMHIR6r162c/CqKb8e3fpE/Dgo54WEUG89iol1dKgzo1pftRTUKmYRgtAQCkE0Y+0oUGkMZhS251P5z9oURrPMJHPMJt+32PXPH3j+S08QsDoyDsLQMASDeEj3SyZYvI3r2Rx32+uLqgmsHi9c9/jDlawt4yAIBkI3ykm9xcy1UvhV1aysPzJjp6CfPZY2avijpawt4yAIBUIHxkUDHqxasWWG5QZ/l0HUiJsjleMPaWAQAkE+EjE4pRw2gAySuL3DemqthbBgCQTISPTGARQJY8ea2jUZDG9WtWe48aAADcRPjIpABiUYxqF0DMYHF/4XGB++GPO92jBgAANxE+sqAYVQPItJl3WwaLc45v4coeNQAAuIW9XVKoWnu0PPusyNVXRxzWzeusGog5fS/2jQEAJPr7m/CRIk67jsYMAxat2Cu+XiO57dsl7JoAAAhH+EhzZtfR8A/ejBHmdIjjMGCzF4zTXXLjuSYAAKr7/U3NR5I52aNFH3/98x+ct0XXkLFnT+QL2oWSKl4TnVABAG4gfCRZrD1azK6jd85eFV8YqFHDeqRDA0jXrq5cE51QAQBuIHwkmdNuolt3WIxkOAkDGkD+9rfQY8uXRx0FcXpNdEIFALiB8JFkbnYTtQ0DN9xgPwqybl2Vr4lOqAAANxA+kkxXq2jRaLSuo03q13InDFgFkHbtIkZBnFwTnVABAG4hfCSZLpPV1SrRuo6OLTzOvTBg0xk1OIA4uSY6oQIA3EL4SAFdshqt6+g5xzd3NwzYdEY1AkiXLjGvaVjv9lK+t1KK1m9hxQsAoNro85FCsRqIJaTp19Sp+2pCwu3/1yD4mjaW7JAXPvpOftpeHjgtr2Eduec8mo4BAELRZCyLJKzdudXqlzVr9tWE7A8+f35ume3Tp9B0DABQxe/vGlEfRcpp0Cho08T9F9bMGR5A2rc3flRUVMqoV1ZGffroV1ZKn4551IEAAOJGzYeX2RSj5ubmyLad9n1G1K8798iSb7Yk8OIAANmK8OF1NsWoG8efK+snnBf1qVqACgBAvAgf2EcDyN//HnIo119phJAoT0r4ZQEAsg/hAwdcd53tKEiHn7+JOF5wVNMkXRgAIJsQPhBBC07DvfHMLSGjIAfXqyndE1EICwDIeoQPRNAVLPNX/iBtbpsd8ZgZQB66oBMrXQAAVUKfD9jSXh/3zPlClvy/PtYnRPlXJ2H9SQAAaYk+H3CFNhHTXh5Fl5ZI0/vHSLtpT4aeoH1CLAJIQjqzAgCyBiMfqH5n1KIike7dA8HjpueWRayDMZ+l+8eYAYTREQDIHox8IHGsOqMWFAQKVXXEwyrN6jF9lj6uoylvry5mdAQAPIqCU1QtgOzZY9kZNThMRDxNxHh80sK1xuhI+LnFpbuM4zp6AgDIXoQPVE2NGrY9QaI3JhN55oONtqMjSkdEdEoGAJCdCB+oHg0gI0dGHI4WQLb9vifm6IjWggAAshPhAyF0xEH3bJm9YrPx09EIxEMP2Y6CnLxpVeC+b39zMie0CBUAkJ0oOEXUJbJ5DWvLoFOOkNZN68dekWJRjPrSC6OMn/kj5xo/B/fIl8cWrIl5LfpeAIDsRPhA1CWyxWXl8tiCtc5XpPj98uaKTdK3yxEhhzeMP9fomqorXWZ8/J1RXGo1pqLRJa/RvpADAMhOTLvAmFqxWyIbzsmKlL6dW1nuD9OvUwtjRYyGFxU+fmLe18fp9wEA2YvwAaO4M9oS2aqsSDHCg07DDBliGUK02ZiOcATT+8FNyAAA2YlpF8Rd3Bm8IqUg1s62Tz217xZWC6IBpM8b82Vpu+50OAUAjyF8oMrFnXGFFoti1Nz+/cTojZpeHf4BAAlG+IAx4qCFpHZFoK6FFg0Ze/eK1KzpaIM6O+wJAwCZjfAB44tbizy1kFS/wmPFgPAVKXGFAbMzavj+MOb9GCGEHXMBIPOxqy2ifrFLjN1pqxUGrr5a5NlnI4/b/CsZz465AID0/f4mfCBE8CjGxpKdMn3pd1JcZh0sXAsD4aMg6rXXRM49N+S6Thu/0DYYmaMxi0f2YgoGANL8+5tpF4TQL+7gFSxDe7W1nFKJ1htEj+nXvz6uTcVihgGraZiBAw885mA5cFwrcAAAKUX4QFxhxFSVMBC1NkRDRkXFvpoQi2JUpytr2BMGADzYZKyiokLGjBkj+fn5UrduXWnTpo2MHTtW0mx2B9UUbxjQKRqdNhk0dYncOmOF8VPvh3RKzc21rvfw+aSwS0tH78eeMADgwfAxfvx4efLJJ2XSpEny5ZdfGvcnTJggTzzxhNtvhRRy+iWv55m1IeEjJbat2jWAXHyx5S65dhM4vv31KOwJAwAeDB8ffvihFBYWyoABA6R169Zy0UUXydlnny1Lly51+62QBr1BYoWBE488JGptiG2r9pkzLUdBdIO6fl9/GPFeij1hAMCj4aNHjx7yzjvvyJo1+7ZN/+yzz2Tx4sXSv39/y/PLy8uNCtngGzKnN0isDeI+/fZXx7Uh1idEBpAprz5ojIKY2BMGADxecDpq1CgjQBxzzDGSm5tr1IA88MADcsUVV1ieP27cOLn33nvdvgwkgX7Z65d+eJ+PvKDluLNXbK5+DYlNMaoGkKJ1JXQ4BQCvh4+ZM2fK888/Ly+88IIce+yxsmLFChk2bJi0aNFCrrnmmojzR48eLSNGjAjc1+DSqlUrty8LCaIBQ5fT2q1iiac2JCqzGDVsSW5B26bGz4qKSlquA4BXw8dtt91mjH5cdtllxv1OnTrJt99+a4xwWIWP2rVrGzdk33JcJ/vGhLdqj0kDSGGhyJw5odeQmyODRs4N3KflOgB4qOZj586dkpMT+rI6/VJZWen2WyGLakPiGqWYPduyFkSnYc5b/W70lTQAgOwLHwMHDjRqPObNmycbN26UWbNmyaOPPirnn3++22+FDKsN0RGOYNUtFNWplnCPv/aIEUKirqQBAKSU63u7bN++3WgypqHj559/Nmo9Bg0aJHfddZfUqlUr5vPZ2yV7xbX7rQNF67cYzcpyKivkm4cLIx5vvX8aZvqQ7rRcB4AEY2M5eCKw6Eoa7ZZqCl5+G2z28u+lsPPhSbtmAPCiMjaWQzbQeo3wZbzBhaThK2R0pOPFF0ZJt02rQo4brdnTK2MDgKe5XvMBuMFJS3arLquXXv5QYLolhC7RnTYt8RcOAIiJ8IG0nGpx0pJd2a2kybcKIIMHR/QJAQAkH+EDaUdrPJy2ZI+2kmb+yh9E9u6NfAECCACkFDUfSDtRW61bnBery6pVZ9TAfWpBACDpCB9IO1VpyR6ty2ogZPTqJbJoUWQIIYAAQFIx7YK0Y1VIGkyPN4+nJbtp4ULroKEB5Omnq3StAID4ET7gjZbswawCyHXXGSFEi121eZn2ENGfdEcFAPcx7YK0ZBaShvf5yHNrwzgNIBUVIjVC/xNggzoASDw6nMJTLdkt2ax+0X4h5iPV2YMGALygLI7vb6ZdkNbMQlJtj64/XQ8e+zeoW9q2a8RxNqgDgMQgfMDzdGTlkgvvs+yMqgHkiuWvB/qKAACqj/ABzwvuK2IVQO5/6/+MEOK0/wgAIDrCBzzPaoO6/NvnRJxnbFAHAKg2wgc8z6qviN+XY79BXQLbs7PUF4AXsNQWnmf2FdHdcjVW+MM2qJvxwijptmlVwjuj6k694UuLWeoLIBsx8gEE9RWx2qDu19ffsu+MOnmya8FDw0/4hnrFpbuM4/o4AGQL+nwA8fQVsZtyCfvPKJ7+JHruaeMX2u7k69sfghaP7JWQpcYAkOzvb6ZdgCCONqirrNRWqLbTMPFOn2hIsQsexluKBJb6Rr02AMgQTLsA8crJsZ+G8fninj5xuoSXpb4AsgXhA6gqDSBnnhlxeMP4cyNPjdIpNXyprx2n5wFAuiN8ANWxcKHlKIg2Jbvm09dsp09iLfUNpsf1cT0PALIB4QNwg0UAuXfB34wQEmv6xFzqa1f5rcf1cYpNAWQLwgfgkqJ1JZadUcMDCNMnALyO8AG4RKdF8g6uZzQmswogerOaPtEaEK0FseNzsKsunVEBZBLCB+ASc/pEaQBZ0ObkiHOK7ugdMX0Sz1JbK7qCRvuEDJq6RG6dscL4qfdpTAYgXRE+gAR1Sr3+orvt94f5v/8z/lFHKD5Y90uVl9rSGRVAJqLDKZAA4R1OC9o2tTyv4MEFUUc9gk0f0j2kyRidUQFk6vc3Ix9AAjulFnY+fF9g0IxfUWE5DROL3VLb6k7XAECqED6AFHdGNYtRrZjjFVZLbemMCiBTET6AFCzJfatd94jjVgFEp020hsRqTxg6owLIVIQPIMl0JOKGC+60LEbVAHLVsn3Hh57Z1qjXsAoeis6oADIV4QNIsqYH1Q78s1UAGfv2FCOEaK1ItELR4KW9vjimawAg1QgfQLKFlX1oAGl9e+g+MOrUdoc6Xtp7WMMDgUbpfbvpGgBINcIHkGQlO8ojD/p89j1B9BaT3dhHdHRGBZAKNVLyroCHRSsA1QAyffpoKfhuZegDGkAsVsqYTcbCH/mpbF+TsWijH/pcbdsevFxXa0R0qoYREwCJxMgHkGSxCkUvHzTOaD4WQQPIffdF7AljNVZhHrPbE4bOqABSifABJJnTQlGrkQ65++7ANExVm4xVJ7QAgBsIH0CK94CJ2tdDA0hlZeQL+HxVbjJGZ1QAqUbNB5AiGjD6dMwL2QNGp2Qilsaa9R5hhaeFXVpKoc1y3Wg1JnRGBZBqjHwAabQHTNSeHBpAevSIOGzXml1smozRGRVAqhE+gEzywQe2+8MMW/x8xPHzTmgeEWjojAog1QgfQCayCCDDPpgeMQoy57MfIwpH6YwKINUIH0AGb1Bn1Rk1OIDYFY46LngFgASg4BTIUEZB6P7OqOEjHuZ9fcyucNRxwSsAuIyRDyBDBReEasj48tDWEedoCIlWOBpXwSsAuITwAWSo8MLR/n+aZLnstqBtU5Hhw5N+fQBgh/ABZCi7wlHLvh8TJzrcoA4AEo/wAWQwu8JR3Rtm/uebI59AAAGQBig4BdKcLpWNVhQatXDUojNq4L7V3jEAkASEDyCNOd323iwctaQh48QTRZYts27bDgBJxrQLkKZc3fb+00+tg4YGkFtuceFqAcA5wgeQhhK27b1VAHniiWrXguh1FK3fIrNXbDZ+xn1dADwlIdMumzdvlpEjR8obb7whO3fulLZt28ozzzwjJ510UiLeDsg68Wx7bzvdYvtk/75bTo6jaZhYNSdOp4YAIGHh49dff5VTTz1VzjzzTCN8HHroobJ27Vo55JBD3H4rIGslfNt7n7Ni1FjBwpwaCo8s5tQQrdoBJCV8jB8/Xlq1amWMdJjy8/PdfhsgqyVt23sNGZ07i3z2Wehxn0/mr/wharCYfHlXGTvPfmpIY4wGF12JQ+dUAAmt+ZgzZ44xvXLxxRdLs2bNpEuXLjJ16lTb88vLy6WsrCzkBnhdUre9X7HCcrqlX6cW8sD8JyKOm2eOmb3K8dQQACQ0fHzzzTfy5JNPSrt27eTNN9+Um266SW655Rb55z//aXn+uHHjpFGjRoGbjpoAXpeSbe8tAsjln70ZsWmdcaqIbNmxO7FTQwCyls/vd3ehf61atYyRjw8//DBwTMPHxx9/LEVFRZYjH3oz6ciHBpDS0lJp2LChm5cGZJyUFHNaFaPatW13YPqQ7vEXxQLIOPr9rYMITr6/Xa/5aN68uXTsuO8vNlOHDh3k5Zdftjy/du3axg1Ammx77/NJ0bqSfRvSBTFHQIJDSOP6NeXXHXss6z70CvPcmhoCkFVcn3bRlS5ff/11yLE1a9bIkUce6fZbAZ6Qim3vNTDo/jCrDmsT8ZiGELPm5P7C41yfGqJnCJD9XB/5GD58uPTo0UMefPBBueSSS2Tp0qXy1FNPGTcAmVVzMrD0f437G8LqPvT+5oEXyeGjX5Inc3wRU0N5VZwaomcI4A2u13youXPnyujRo43+HrrMdsSIETJkyBDX54wAJFZwGLAqPDX4/bJ7b6U8W7RRvt26U45sXE+uKmgttWrEN7Bq1zPEHDehZwiQ3uL5/k5I+KgOwgeQXkI6nB5UWwraHRpxjk7RVGe0Qt/jtPELbZfumvUji0f2omcIkKbi+f5mbxcAzmtOtAjV4u+Vojt6h4yMxLv5XTzt5AFkPsIHgPj5/eLv1CnisBlA4t38LuHt5AGkFcIHgCpZMmuRZe8PDSATXp8YGK147O2vY65aSVo7eQBpgfABoErMUQirAHLJygWBUZBJi9bLoKlLjJoOu2mYpLaTB5ByhA8AVRI8CqEBpPXtr0Wc47QOJCXt5AGkDOEDQJVEjFb4fLbTMHqLVQeiK2N0Oa2uagmm91lmC2QXltoCqDKzN4cK/kXy6r9GSOcf10Scb4aTaPu9hCztTUY7eQCuoM8HgKSx6kpqsmpMNv34s6XeP582lu4CyB6EDwBJZY5WfLCuRCYtWhfyWLTOqACyB03GAKSkEdnwPu0jVq3YFaNqjQgAbyJ8AHCN7aoVn0/yLYpRjQASFkLY1RbIfq7vagvA28xVK1Y73c5f+YP0GzpI5D//CX2SBhC/n11tAY+g5gNAQsRctWIx7fJipz4y8pxbQ46xqy2QGSg4BZAZbOo+wvuFsKstkP4oOAWQGfRvH4u/f8JXyLCrLZBdCB8AUm728u9tO6MGY1dbIDsQPgCknNaE6FTL4iNPiHgsOICwqy2QHaj5AJAWxam66625ysWqMdnsk/rLuR/No+YDSFPUfADIKBoozjvhwEoWqw3qCj95Q3Jznf/KctIvhJ4iQGrQ5wNAyumX/pzPfgw5ZgaQiFGQ/T1BonHSL4SeIkDqMPIBIOV0FYvVxnR2oyBWnVHDd9oNf73i0l3GcX3cyTkAEofwASDlYq1i0QDydttukQ9YtGbX0QyrcRHz2D1zvpB75kQ/R1+DKRggcQgfAFKu6UG1Y54z5MIx8sHaX6wDyJ/+FHMERWmcKC4rl+Ky6OfQUwRILMIHgNTzx3GeVb3HM88YIcTNPiD0FAESh/ABIOVKdpQ7Oq/om5J90yE2nVELu7R07ZroKQIkDuEDQMo5/aKftGi90Q8kUBBq05rdqk9IYI+YhrUlr2GdwIZ1Vuc0qV9Likt/Z/ktkCCEDwAppzve6jJXJ+3DIlakaAA5//yI88IDiPna95x3rNxzXseQY8E0amzZsVuGz/xMBk1dEhp2ALiC8AEgLZqMaX8NFSuAWK5IeeUV21GQR+Y9Zvyz7or75JVdjR4eetN/1mOxsPwWcB/t1QGkDavGX9FMH9JdCto0CT1o0/+joqIyojW7hhdd1aKrX8bO/UK27thjP13TqI4sHtmL9u6ADdqrA8hIOiKhX/BDz2xb9RUpNsWo2po9vJ260vCiNSB2wcNq+a1VW3ZatQPO0V4dQFrRkYVT2zaVSYvWVa9QVQNI2CiIBpCCoK6pZjv18r2VjsOO1ejMwfVqGj+37TwQYGjVDthj5ANAxhWg6nF9XM+LSgPIxRfbFqOa9RwbS3Y4ui49z6otu4aO4OAR/NrUigCRCB8AMqoA1byvjzupv6iY8aIUPLjAMoA88epDxj9PX/pdzOW3Gnb0vHj6oSlatQORCB8A0pLdipTgVStOmC3XrTaoO/frxbJh/LlGy/VBpxwRNexcdvIRxnnxoFU7YI2aDwBpSwNGn455xpe31ltojYdOtcSz4iS4KNUMIOE9QPT+7Mu+N0JNeD1HXpx1IbGuAQDhA0Ca06ARsZw2DlZFqRpCwgOI2Zq9T0WlZdgxV8e4dQ2AlzHtAsCTxasaQN5s1z3ifGNFTJsmUtj5cOOnOcoSTxfWuAtjAY8hfADwbPHqny+4U/ItakGMJboXXeT4dazEWxgLeAnhA4B4vXjVqimZvPxyRJ8Qu9fRPh9mr4/w16bPBxCJ9uoAPMNspx61eNWqPXvYr0mr11HVKYwFMl08398UnALwDEfFqxadUQP394cQu9epTmEs4CVMuwBAOA0ZF14YeXx/CGEfF6B6GPkAACv//ve+nxajIAs79ZQh5/x3QvZxcTQ1BGQ4aj4AwIa5iVzRHb0tHzeblpnRoLoFplab1rFBHTJFPN/fTLsAgE0QMDeR05Bh1Z7dbFTmxj4uwe8XjA3qkI0IHwAQRgOEBonwGGEXQPRWnX1c7N5PsUEdshHhAwBsNqOzogFkVseetqMgVdnHJdr7KTaoQ7YhfABAmFgBYvjA/7YdBTlt1J9df794zwPSHeEDAKq4EZxVAGny5lzrRmUuvB8b1CFbED4AIEw8m8hpALHdH8al92ODOmQbwgcAhIl3Ezndx2X+yh+sA4iDEBLt/digDtmIPh8AEGffjTEDOsoh9WtZNwIbNEhkxozIF3Pwq5Y+H8hk8Xx/Ez4AIBEdR61GPM45R2TevMS8H5BihA8ASAd2Uy7p9WsXyL4Opw899JD4fD4ZNmxYot8KANKLhgyroBHnahgg2yQ0fHz88cfyt7/9TY4//vhEvg0ApDe7AEIIgUclLHz89ttvcsUVV8jUqVPlkEMOSdTbAEDmBJArrog8TgCBByUsfNx8880yYMAA6d3bejdIU3l5uTFPFHwDgKz03HP2oyD9+6fiioCUqJGIF50xY4YsW7bMmHaJZdy4cXLvvfcm4jIAID1pAAkf8Zg/f98xilHhAa6PfGzatEluvfVWef7556VOnditgEePHm1Uxpo3fT4AZD2KUeFhri+1ffXVV+X888+X3NzcwLGKigpjxUtOTo4xzRL8WDiW2gLwnBhLcun9gUwQz/e369MuZ511lqxcuTLk2ODBg+WYY46RkSNHRg0eAOBJGjKuvlrk2WdDj/t8Rtt2up4i2ySlyVjPnj2lc+fOMnHixJjnMvIBIBu42Rn13fwT5dpLDtTGmWc8eWVXAgjSRkpHPgDA66q1R4tFMWrPDZ/KxvHnGjvoGqfsDyD6Hn065hmhhqkZZBLaqwOAy8HjpueWGQEhWLyjFUXrt0hB26YRx1vf/lpIOJk+pLuU/r6bqRmkXFq1VwcAr9DRBw0BVn/Rmcf0cT0vFh3BMEc6gm2cMNAYBTEtWF1shJ3g4KGKS3cZxzUMxfu/QYPP7BWbjZ9OrhWIF+EDAFyi0x7hISCYfo3r43peLDp1ojSAzDj+7IjHzQAya8VmV8KO0qBy2viFMmjqErl1xgrjp96PN8AAsRA+AMAlOlrh1nlas6FTJzrBMqr/LdajIOPPlSefGuFK2DGni9waQQGiIXwAgEvM0Qo3ztNiUa3ZUGaFh1UA6fb9FyHTMFUJO25OFwFOED4AwCXBoxVW9Lg+ruc5ocWiWqCa1+hAWNEAUvDggohzjQBis34gVthxc7oIcIKltgDgEnO0QqcpNGgERwEzkOjj8SyB1QCiy2nDl9HK6MgluVqMGjxCoo/mOQg7bk4XAU4w8gEALrIarVB638ky27hWm/j98n3hJZajIPGEHTeniwAn6PMBAAlQlaZfVs3JDq5X0/i5bece2x4e+rx+nVpEvF5px+Ol0RefObpWXdWixaVWXwjmCMrikb1oXAZXvr8JHwCQxs3JrFg1LNMAkZtrM5jt4Ne8+f7G6THeC7BCkzEAyCDRVpuIwxUoxoiEhgyroKG1ITECSHWni4B4UHAKACkWa7VJrBUoBW2ahD0YWYwqOfv/1owSQuyKW5lqgdsIHwCQYtVZRWI+N6LGpKJSci8fJPLii1FHQaxqUyLCDOAywgcApFh1VpGUbC+X1z//QcbO+zJk9CSvYW0ZdP190nrU/0hhl5aRAeToo2X+vxexIR1SgoJTAEixWKtN3GDXBTW8ayoFpqgqCk4BIINYtVJ3W/7IucYtVmdU2qkjGQgfAJAG7FabHFKvZqDXR3WYMcKyNfuEgSEjI7RTR6JR8wEAacK2lbqITPtgg1HXUR1mqHhk/pfSZsRNcv7qd0Me1wASPA1DO3UkCiMfAJBmUzC62qSw8+HGT72vt6YNarv4Lj4ZPvC/LXfJ1QAy/x83G/9MO3UkCuEDADKAm0FAQ425+65VADmm5FsjhDjdfReIF+EDADKABgEzMFSVPldfo/tRTUIKXDWAWIUQo117ei2IRJYgfACAB1bEhO9ya1XgahVAjM6o4d1SgWqizwcAZBCrnW+dsGseZrn77ojhIv/7v5Evsv/roio79iL7lbGrLQBkL/PL/4N1JTJp0bqY548Z0EGuPTU//oBgMeJR2qGT9LvqMbqiIgJNxgDAAytihvdpb3zxR6OPVyl4KIu/TRt9uVKK7ugdckw7s9703DJjVAZwgvABABleB2IXK3xBNR7RRlGK1m+R2Ss2Gz8juppqALEIIcGdUemKingx7QIAWVgH4mQqJJ7naTApaNvU8nWCC1WnD+nOrrgeVRbH9zcdTgEgSzujRhvx0OChUyXhf32aUyjhG8vp62rIuO+tJ+Xq5fNsO6PSFRVOMPIBAB7dRTfaihkdAVk8slcgwOjIx6CpS6Lukruk1XHiX/QuIx8eVUbBKQDAjo6QxFqqq4/rfjJmDUd4kzOrniDdN62ynZoBghE+AMBjisucTY3oRnY6QvL65z8YgeWc4/JCpmnsOqMaS3TTa1AdaYaaDwDwmK2/lTs+V0dA/uuF5SHHdCYmeFFLwYMLIpbfGp1RFSEEFhj5AACPaVy/VrWebwaPM9o3NRqY/ee2M/eFjFGjIk9OUmv2mEuGkVYoOAUAjwkvHq2uiOW5VoGjd2+Rt9+WdFpqDHdRcAoAsGUWj7olosOp1d+0CxYkZBTEXDIcXkBL19X0RvgAAI+J1Rk1XpYdTm06o1alGNVqSkVvurfNqJdXRvQqsb0mpA0KTgHAg3Q6QhuJVWWHXCv69a6vo6tiQvp8aNAIH/GIoxjVakrl4Ho1jZ/bdu6p2jUh5Rj5AAAPBxBtJKYt0f90amvjWHVHQyw7nGrIuOeeyOMxpmHsplQ0dMQKHjGvCSlF+AAADzN3yL1r4LEy5cquklfNWhBt7W45XXLlUKmoqLQOIP37RxzW5+qIhxsTJsHXhPTAtAsAIGKPGG1ENnbuF7J1h7MRBh3D0OCixax20yV5DevIoLfXyK192oc+ef78iFoQJ11Y470mpA/CBwAgYiRE1a2ZY7n5XDhz8kSLWPX5tpvWle2Sxxaskcf2d0WN2B/G55OKvRWSm5tT7amS8GtCemHaBQAQtSg1fFlu+He5ji6Yu+DGM11i1Zo9t0auEUKqO1USfE1IPzQZAwBEpYFCp0F0NEJDwYlHHiKffvtr4L5Oa9jtfuvEdUtnyZhF/4g4rm3btV9HPF9SuhJm8qCu0r1NE0Y80vj7m/ABAHCNFpfeOmNFlZ4bMQ0jIm+16y43XnCn46kfRjtShw6nAICUqM50idU0zNlrl8iGsFBySL2agV4fJqZZMgsjHwAAV6doThu/MO7pEiejILOXbZJmDesa0zz6Ps8WbZRvt+6UIxvXk6sKWkutGvw9nUpMuwAAUsZc7aLcDiDG66/8gY3k0hDTLgCAlK+SqWrDMt/+MGE0JZs4MfL1O7VgI7kMx8gHACDhq2Q2luyQ6Uu/k+Ky8qoVjlq0Yl/Q5mS5/qK7Q56rgUdbxrPSJfmYdgEApP2S3V937Jax8+KYPrHZCya8UFX3qmEjufT+/qbDKQAg6d1TTX2P29fO3apnSLjZy783lvGG14Lo/da3vxYIJ2wkl/4IHwCAtAoksZbx6khHRACZMDDwGBvJpT8KTgEAGUFHRXRaxrc/ZNzW/5aIczSUsJFc+iN8AAAyZpRE60GUBpCXjj/ben+Y3ByRoUNTcIVwivABAMjoZbxWAUQmT7YtUEUW1nyMGzdOXnnlFfnqq6+kbt260qNHDxk/frwcffTRbr8VAMCjAaRPx9BC1d33Vxib3RW0bRp6sgaQykqCSJpxfaltv3795LLLLpOTTz5Z9u7dK3fccYesWrVKVq9eLfXr14/5fJbaAgDioY3Fgjue2nVG1aZlTlfWVHcZsZuvnSnSqs/HL7/8Is2aNZP//Oc/8oc//CHm+YQPAEC8rdzDv8jO/fJ9mTRnfMT5wVM0brVkDw8/br52Jkmr9up6EapxY+vq4/LycuOCg28AADgZbdAvfau/oOd2OF3yLWpBdFTkznemutaS3Qw/tHuPT0LDR2VlpQwbNkxOPfVUOe6442xrRDQpmbdWrVol8pIAAFlCpznCv/SD+W2KUa//ZLYRQszQogFGg4yb4ae6r53tEho+br75ZqPeY8aMGbbnjB492hgdMW+bNm1K5CUBALKE006mGkCsQohRG+KvNAKMBhk7Gh6K1m+R2Ss2Gz/1vt6mfbAhZviJ9dpelbAOp0OHDpW5c+fKe++9Jy1btrQ9r3bt2sYNAIB4xNvJ1Koz6oYJ5xk/Z1/2veMN8Q6uV9P4uW3nHkfvS7v3JIQPrV/9y1/+IrNmzZJ3331X8vPz3X4LAAACHU+1vsIfRwA5e02RPDXrgZDjhV1a6heYZfFoOKehw0S79yRMu+hUy3PPPScvvPCCNGjQQIqLi43b77//7vZbAQA8LLzjqVNvtS+wbkzm88nqm26LGjziodek4Yh270lYauuzaeTyzDPPyLXXXhvz+Sy1BQDEw8lohRX9ttpg0xPEMpzE+dpKu7F6ZbltWTr1+YgX4QMAEC+zTuODdSUyadE6R88J6cVh8Ydz/u1zxO+r2gQBfT4aRj2X8AEAyKoQctr4hVHrQLRgdPKgrtK9TZNAF1JdyWLUfbgwCjJmQAe59tR8OpxGwcZyAABP1IH49t8euqCTnNquqXGuuYx27U/bjZBx5SVjI17Trl27XY2HF4NHvBj5AABkHSctz/Wce+Z8EbKMNlrgeLDnYHmq24WW7+fFGo9wTLsAADwv2mZvGjz+/NyyqM+3G/HofO+bEUtuvVjjEY7wAQBAlFBy4v1vO+7XYRVCKvbslaXfbvP0LrbV+f5OWIdTAADS0ZL1WxwFj5t7tpHT2h0qFQ9WSm5uaIlkbs0aUqD/kIS/3yuijOBkKsIHAMBTir4pcXSerr4taNNk3x0NGR9+KHLqqZEnJTCAzHdQu5KJWO0CAPAYX9XO69HDOmhoAHnqKUlE8LjpuWURzdN0GbEe18czFeEDAOApgdGMqp5nFUBuvNGyUVl1plrufW21Za8S85g+rudlIsIHAMBTuh/VJLAzrZ1D6tU0zrOlAcRuFKSy0vhHs4eINjDTn/EEhaUbtkZtF6+vpI/reZmImg8AgKdosaY2Gou21HbcBZ2cFXVqAAkf8cjNNX6c9uCCKtdq/Lzd2T41Ts9LN4x8AAA8RwPAlCu7Sl7D0O3uNSDo8biKOTWAfPxxxOGiO3pXuVajWYPQ66rueemGkQ8AgCdpwOjTMc+dZawnnWQ5CqI9Qkb3HSrTO/czpkp8+2s1+nTMs30fnZ6p9Pvl4Lo1Zdvv1kuC9Zl5jfZdbyaiyRgAAC7R2o6Ctk1jblA3fUh3y4JWq6W1mdLKnY3lAABIAR1B0ZBhtROujoL4/PuKUa1qNeyW1obTEY90Cx7xYtoFAACXBNdgaAAJb82+YcJ5xs+iISWOl9aadIXO5EFdpXubJhnf4ZSRDwAAXKI1GFq06gsKIP0HPx5xXkHY1EyspbVKW8J/VVwm2YDwAQCAS3REQpfTKjOAfNnsKMtpGNHi1Jkz41oyO3bel3La+IUZ3d1UET4AAHCR1mJoTYbWZgQreHCBlDcOKzK99FIjhMSzZDYb2quz2gUAgGTvRuuLrNk49s55smOPs69kc6nt4pG90qb+I57vbwpOAQBIAA0FUfeH8YWGhi/uH2D8tJyiidJe3eleNemEaRcAAFLB7xdZvTricPgKmWhorw4AAOLToYPlBnUaQM798r2YTw+uFanORnbJRs0HAAAp9o/3v5EeF54lHX7ZGPGY1TRMeM2HVWdUq43sotahJPH7m/ABAECS2H35795bKceMeUN0sMJq2iX/9jni9+VYtlc3O6OGf5lbneckoFQV4QMAgDQT68t/3Our5W/vbTCOWwWQLXUbyom3vBDyHA0z2vfDrkGZOUIyZkBHufmF2AGlOggfAACkEaejE+NeXy1T399gjIAcXvqzfDDlTxGvVVFRGZgq0dqOQVOXxHz/xvVrydYduxO6bJeN5QAASBPR9m3x7/+pj+t5o8/pKF+N7S9jBnSQs/qdLP94b33Ec3Jzc0SWL49rtYtd8Ahftpss9PkAACCBYu3b4g/r2VGrRo5cd/pRQSf4RW67TeSRRw4c69rV+NFsXegGddWRzGW7jHwAAJBATr/Uf4523sMPWy7J1Q3qmjesHZi+qY54WrxXF+EDAIAEcvql3szJeRYBpOj/9ZFJrz5U5QCiz9MiVl15kyyEDwAAEki/1PXL3efWl7/fL/LTTyGHBny9WDbE0Rk1+L2Vrp5J5h4xhA8AABJIv9T1y1353Pryb9bMtjPqscXrHL+MrnJxY5ltvFhqCwBAEiSsydejj4r89a8Rh6NtUDf0zDZyattD6XBqInwAALJVItubS9guuar17a+FHHerp4cV+nwAAJCG9Au/oE0TKex8uPHT1QCgYwlHHBFyaOOEgTJ60dMpre+wQvgAACBbfPutyNbQZmE3Ln3FqAVJVX2HFaZdAADIRr7I0Y2KbzbI0soGKd/Vlg6nAABkI79f5K23RPr2DRzKPSpfWhycJ4Nu/Lvru9rGg2kXAACy1dlnRyzJPXJbcWDX3OLSXcaGd7oSJ5kIHwAAZPkKm4IHF8jsDmfE3NguWQgfAAB4YGO7W8+7TY4dNtM4dkffmwOPs6stAABwVfCGdTtq17NtPsautgAAwBVN69d29Tw3ED4AAMhmPpfPcwHhAwCALFbyW7mr57mB8AEAQBZr1qCOq+e5gfABAEAWOyW/sdFMzG5WRY/r43peshA+AADIYrk5PqOLqQoPIKnabI7wAQBAlut3XHNjUzndXC5Yqjabo88HAAAe0O+45tKnY57RTCwRG8vFg/ABAIBH5Ob4pKBNk1RfBtMuAAAgS8LH5MmTpXXr1lKnTh3p1q2bLF26NFFvBQAAvB4+XnzxRRkxYoTcfffdsmzZMjnhhBOkb9++8vPPPyfi7QAAgNfDx6OPPipDhgyRwYMHS8eOHWXKlClSr149efrppxPxdgAAwMvhY/fu3fLpp59K7969D7xJTo5xv6ioKOL88vJyKSsrC7kBAIDs5Xr4KCkpkYqKCjnssMNCjuv94uLiiPPHjRsnjRo1CtxatWrl9iUBAIA0kvLVLqNHj5bS0tLAbdOmTam+JAAAkEl9Ppo2bSq5ubny008/hRzX+3l5eRHn165d27gBAABvcH3ko1atWnLiiSfKO++8EzhWWVlp3C8oKHD77QAAQIZJSIdTXWZ7zTXXyEknnSSnnHKKTJw4UXbs2GGsfonF7/cbPyk8BQAgc5jf2+b3eNLDx6WXXiq//PKL3HXXXUaRaefOnWX+/PkRRahWtm/fbvyk8BQAgMyj3+O6gCQan99JREkinaL54YcfpEGDBuLz+aqVwDTAaAFrw4YNXb1GROLzTi4+7+Ti804uPu/M/Lw1TmjwaNGihdFiI6M2ltMLbtmypWuvpx8k//ImD593cvF5Jxefd3LxeWfe5x1rxCNtltoCAABvIXwAAICkytrwob1DdGM7eogkB593cvF5Jxefd3LxeWf/5512BacAACC7Ze3IBwAASE+EDwAAkFSEDwAAkFSEDwAAkFRZFT4eeOAB6dGjh9SrV08OPvhgR8/RelttA9+8eXOpW7eu9O7dW9auXZvwa80GW7dulSuuuMJoSqOf93XXXSe//fZb1Odou/2rrrrK2OG4fv360rVrV3n55ZeTds1e+7xVUVGR9OrVy/i89bl/+MMf5Pfff0/KNXvx8zZ/r/Tv39/o0vzqq68m/Fq9+Hnr+X/5y1/k6KOPNn53H3HEEXLLLbdIaWlpUq87U0yePFlat24tderUkW7dusnSpUujnv/SSy/JMcccY5zfqVMnef311129nqwKH7t375aLL75YbrrpJsfPmTBhgjz++OMyZcoU+eijj4xf0H379pVdu3Yl9Fqzgf6i+OKLL+Ttt9+WuXPnynvvvSc33HBD1OdcffXV8vXXX8ucOXNk5cqVcsEFF8gll1wiy5cvT9p1e+nz1uDRr18/Ofvss41fNh9//LEMHTo0ZutjVO3zNulmmtXZHsKL4v28dRsOvT3yyCOyatUqmTZtmrGHmIYWhHrxxReNDV91Oe2yZcvkhBNOML7nfv7557Az9/nwww9l0KBBxmepv5v/+Mc/Gjf9nF3jz0LPPPOMv1GjRjHPq6ys9Ofl5fkffvjhwLFt27b5a9eu7Z8+fXqCrzKzrV69Wpdo+z/++OPAsTfeeMPv8/n8mzdvtn1e/fr1/f/6179CjjVu3Ng/derUhF6vVz/vbt26+e+8884kXWX2qOrnrZYvX+4//PDD/T/++KPxGrNmzUrCFXv38w42c+ZMf61atfx79uxJ0JVmplNOOcV/8803B+5XVFT4W7Ro4R83bpzl+Zdccol/wIABEb9LbrzxRteuydN//mzYsMGYBtCpluC+9DokpX8xwp5+Pjo0etJJJwWO6eeof1HrCJIdnRbTFK5DprqJ4IwZM4xRpp49eybpyr3zeetfNfpYs2bNjM9dd5U+44wzZPHixUm8cm/9+71z5065/PLLjSFunVpEYj/vcDrlotM2NWqk3bZlKZ0R+PTTT0O+5/Rz1ft233N6PPh8pSMlbn4vejp8aPBQ+ks5mN43H4M1/Xz0Sy2Y/gffuHHjqJ/dzJkzZc+ePdKkSROjm96NN94os2bNkrZt2ybhqr31eX/zzTfGz3vuuUeGDBliDElrjc1ZZ51FXVOC/v0ePny4EfQKCwuTcJXZo6qfd7CSkhIZO3as46kxrygpKZGKioq4vuf0eKK/F9M+fIwaNcqYO412++qrr1J9mVkj0Z/3mDFjZNu2bbJgwQL55JNPjHlIrfnQ+g8vSuTnrSNLSgPe4MGDpUuXLvLYY48ZBXpPP/20eFEiP2+tY1q4cKFR74Hk/v7WLeEHDBggHTt2NMI20l/aj0399a9/lWuvvTbqOUcddVSVXtscFv3pp5+M1S4mvd+5c2fxIqeft3524cVKe/fuNaZT7Iab169fL5MmTTKKlo499ljjmBY+vf/++8YwtRb9ek0iP2/z32n9hRysQ4cO8t1334kXJfLz1uCh/46Hr7S78MIL5fTTT5d3331XvCaRn7dp+/btRlF1gwYNjFHUmjVrunLt2aJp06aSm5trfK8F0/t2n60ej+f8rAwfhx56qHFLhPz8fOPDfOeddwJhQxO0zjHGs2Immzj9vAsKCowRDJ1LPPHEEwO/fPWvba2ZsZsPV+ErLfQ/DPOvdK9J5Oety+patGhhrC4KtmbNGmMZqBcl8vPWv/Kvv/76kGO6RFFHmwYOHChelMjP2/x9rbUIOoWrI0+6LBShatWqZXym+j2nK1aUfq56X1e+2f3/Qx8fNmxY4JiuQtLjrvFnkW+//daoNL/33nv9Bx10kPHPetu+fXvgnKOPPtr/yiuvBO4/9NBD/oMPPtg/e/Zs/+eff+4vLCz05+fn+3///fcU/a/IHP369fN36dLF/9FHH/kXL17sb9eunX/QoEGBx7///nvj89bH1e7du/1t27b1n3766caxdevW+R955BGjon3evHkp/F+SnZ+3euyxx/wNGzb0v/TSS/61a9caK1/q1KljfPZw//MOx2qXxH3epaWlxgqMTp06Gf8+6+oi87Z3794U/i9JPzNmzDBWcU6bNs1YWXTDDTcY33vFxcXG41dddZV/1KhRgfM/+OADf40aNYzfz19++aX/7rvv9tesWdO/cuVK164pq8LHNddcY/zHHn5btGhR4By9r0txg5fbjhkzxn/YYYcZ/88566yz/F9//XWK/hdkli1bthi/HDTo6Rfc4MGDQ4Lehg0bIj7/NWvW+C+44AJ/s2bN/PXq1fMff/zxEUtv4d7nrXQ5XcuWLY3Pu6CgwP/++++n4Oq983kHI3wk7vPWn1a/7/Wm5yLUE0884T/iiCOMpci69HbJkiWBx8444wzj+zN82XL79u2N84899ljX/0D06f9xbxwFAAAgw1e7AACA7EL4AAAASUX4AAAASUX4AAAASUX4AAAASUX4AAAASUX4AAAASUX4AAAASUX4AAAASUX4AAAASUX4AAAASUX4AAAAkkz/Hxk4wu94bmu2AAAAAElFTkSuQmCC"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最终拟合的权重 w: -10.171807289123535\n"
     ]
    }
   ],
   "execution_count": 29,
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 数据准备\n",
    "x = -1 * np.random.randint(1, 100, 100)\n",
    "y = -1 * np.array([i * 10 + np.random.rand() * 100 for i in x])\n",
    "y = y + 100\n",
    "\n",
    "# 将数据归一化到 [0,1] 范围内\n",
    "x = x / 100.0\n",
    "y = y / 100.0\n",
    "\n",
    "# 将 NumPy 数组转换为 PyTorch 张量\n",
    "x_tensor = torch.tensor(x, dtype=torch.float32)\n",
    "y_tensor = torch.tensor(y, dtype=torch.float32)\n",
    "\n",
    "# 初始化模型参数 w 为可学习的 Parameter，设置 requires_grad=True，表示w参数需要求导，需要计算梯度\n",
    "w = torch.nn.Parameter(torch.tensor(0.1, dtype=torch.float32), requires_grad=True)\n",
    "b = torch.nn.Parameter(torch.tensor(0.1, dtype=torch.float32), requires_grad=True)\n",
    "\n",
    "# 定义优化器 (SGD - 随机梯度下降)\n",
    "optimizer = torch.optim.SGD([w, b], lr=0.01)  # learning_rate = 0.01   # w = w - lr*w.grad\n",
    "\n",
    "# 训练循环\n",
    "epochs = 200\n",
    "for _ in range(epochs):\n",
    "    # 遍历每个样本\n",
    "    for i in range(len(x_tensor)):\n",
    "\n",
    "        # 前向传播: 计算预测值\n",
    "        y_predict = w * x_tensor[i] + b\n",
    "\n",
    "        # 损失函数: 平方误差\n",
    "        loss = (y_predict - y_tensor[i]) ** 2\n",
    "\n",
    "        loss.backward()     # 反向传播\n",
    "        optimizer.step()  # 更新参数w、b的值\n",
    "        optimizer.zero_grad()  # 清除w之前的梯度\n",
    "\n",
    "# 最终预测结果\n",
    "final_prediction = w.data.item() * x_tensor + b.data.item()\n",
    "\n",
    "# 绘图\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, final_prediction.numpy(), color='r')\n",
    "plt.show()\n",
    "\n",
    "# 输出最终的权重值\n",
    "print(f'最终拟合的权重 w: {w.data.item()}')\n"
   ],
   "id": "5417bb360902b197"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "这下，我们的模型中就由了w和b两个参数，对于模型训练来说，就需要找到w和b最合适的值，使得训练出来的函数在样本集上误差最小，如何找到w和b呢，就是根据误差公式分别对w和b进行求导，也就是求梯度，然后逐步更新w和b的值，直到最低点。",
   "id": "458e34689eeb6c32"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## loss.backward()是怎么求导的？\n",
    "\n",
    "loss表面上看只是一个数字，那么为什么backward()能求导了呢？它是怎么知道我的误差函数的呢？\n",
    "\n",
    "在PyTorch中，有一个机制叫做：动态计算图，这个图记录了张量之间的运算关系，例如\n",
    "```python\n",
    "y_pred = w * x + b\n",
    "loss = (y_pred - y) ** 2\n",
    "```\n",
    "这段代码定义了一个简单的误差函数（平方误差）。PyTorch 会将这些运算记录下来，并保存对应的梯度规则。\n",
    "\n",
    "在调用 loss.backward() 时，PyTorch 会从 loss 开始，按照计算图中的依赖关系，使用链式法则逐层计算梯度。例如，在上述平方误差的例子中：\n",
    "首先，PyTorch 会找到 loss 的表达式：$\\text{loss} = (w \\cdot x + b - y)^2$。\n",
    "然后，根据链式法则，分别计算： $$ \\frac{\\partial \\text{loss}}{\\partial w} = 2(w \\cdot x + b - y) \\cdot x $$ $$ \\frac{\\partial \\text{loss}}{\\partial b} = 2(w \\cdot x + b - y) $$\n",
    "最终，这些梯度会被存储在对应的张量中（如 w.grad 和 b.grad）。\n",
    "\n",
    "我们在定义x和y时，没有指定requires_grad=True，所以PyTorch不会计算x和y的梯度。"
   ],
   "id": "54c0a1b0d60a1e6a"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T12:01:43.766988Z",
     "start_time": "2025-06-18T12:01:43.763102Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "梯度 dw: -3.5999999046325684, db: -3.5999999046325684\n",
      "梯度 dx: None, dy: None\n"
     ]
    }
   ],
   "execution_count": 8,
   "source": [
    "import torch\n",
    "\n",
    "# 定义参数和数据\n",
    "x = torch.tensor(1, requires_grad=False)\n",
    "y = torch.tensor(2, requires_grad=False)\n",
    "w = torch.tensor(0.1, requires_grad=True)\n",
    "b = torch.tensor(0.1, requires_grad=True)\n",
    "\n",
    "# 前向传播\n",
    "y_pred = w * x + b\n",
    "loss = (y_pred - y).pow(2)\n",
    "\n",
    "# 反向传播\n",
    "loss.backward()\n",
    "print(f\"梯度 dw: {w.grad}, db: {b.grad}\")\n",
    "print(f\"梯度 dx: {x.grad}, dy: {y.grad}\")"
   ],
   "id": "da559a36ab4b4686"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## optimizer.zero_grad()为什么梯度要清零？\n",
    "为什么要清除梯度，不清清除度会怎么样？\n",
    "\n",
    "梯度表示了参数调整的方向和大小，如果不清除梯度，会导致第二次计算出来的梯度加了第一次计算出来的梯度，可能导致方向和大小都有问题，使得模型训练不出来。"
   ],
   "id": "2a7a8c046dfb8ea6"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T12:02:26.437799Z",
     "start_time": "2025-06-18T12:02:26.433956Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "梯度 dw: -3.5999999046325684, db: -3.5999999046325684\n",
      "梯度 dw: -3.5999999046325684, db: -7.199999809265137\n"
     ]
    }
   ],
   "execution_count": 11,
   "source": [
    "import torch\n",
    "\n",
    "# 定义参数和数据\n",
    "x = torch.tensor(1, requires_grad=False)\n",
    "y = torch.tensor(2, requires_grad=False)\n",
    "w = torch.tensor(0.1, requires_grad=True)\n",
    "b = torch.tensor(0.1, requires_grad=True)\n",
    "\n",
    "# 前向传播\n",
    "y_pred = w * x + b\n",
    "loss = (y_pred - y).pow(2)\n",
    "\n",
    "# 反向传播\n",
    "loss.backward(retain_graph=True)\n",
    "print(f\"梯度 dw: {w.grad}, db: {b.grad}\")\n",
    "\n",
    "# 梯度清零\n",
    "w.grad.zero_()\n",
    "\n",
    "# 梯度累加\n",
    "loss.backward(retain_graph=True)\n",
    "print(f\"梯度 dw: {w.grad}, db: {b.grad}\")"
   ],
   "id": "6a3bd576390aa5d5"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## optimizer.step()如何更新参数？\n",
    "在optimizer.step()之前，已经计算了各个参数的梯度，接下来按照指定的算法来更新参数就可以了，比如SGD的更新公式为：\n",
    "$$ \\theta_{\\text{new}} = \\theta_{\\text{old}} - \\eta \\cdot g $$\n",
    "其中：\n",
    "$\\theta$：模型参数。\n",
    "$\\eta$：学习率（learning rate），控制每次更新的步长。\n",
    "$g$：当前参数对应的梯度。\n"
   ],
   "id": "886faf9b39a90dd7"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "将上述代码改成mini-batch SGD",
   "id": "2db6fba661e0c765"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T13:14:17.974200Z",
     "start_time": "2025-06-18T13:14:17.960442Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.38 0.39 0.41 0.48 0.68 0.44 0.89 0.1  0.09 0.58 0.25 0.62 0.23 0.04\n",
      " 0.07 0.44]\n",
      "[ 5.76460777  5.52254747  5.97929155  6.52056775  8.41687707  5.55359688\n",
      " 10.76442379  2.56347122  2.30029981  7.72274992  4.32264835  7.95595287\n",
      "  3.33162741  2.12223403  2.39160126  5.61032134]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(tensor([0.3800, 0.3900, 0.4100, 0.4800, 0.6800, 0.4400, 0.8900, 0.1000, 0.0900,\n",
       "         0.5800, 0.2500, 0.6200, 0.2300, 0.0400, 0.0700, 0.4400]),\n",
       " tensor([ 5.7646,  5.5225,  5.9793,  6.5206,  8.4169,  5.5536, 10.7644,  2.5635,\n",
       "          2.3003,  7.7227,  4.3226,  7.9560,  3.3316,  2.1222,  2.3916,  5.6103]))"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 34,
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from torch.utils.data import TensorDataset, DataLoader\n",
    "\n",
    "# 大都督周瑜（我的微信: dadudu6789）\n",
    "\n",
    "# 数据准备\n",
    "x = np.random.randint(1, 100, 100)\n",
    "y = np.array([i * 10 + np.random.rand() * 100 for i in x])\n",
    "y = y + 100\n",
    "\n",
    "# 将数据归一化到 [0,1] 范围内\n",
    "x = x / 100.0\n",
    "y = y / 100.0\n",
    "\n",
    "# 将 NumPy 数组转换为 PyTorch 张量，并增加一个维度以适应模型要求 (shape: [batch_size, features])\n",
    "x_tensor = torch.tensor(x, dtype=torch.float32)\n",
    "y_tensor = torch.tensor(y, dtype=torch.float32)\n",
    "\n",
    "# 创建数据集和数据加载器（DataLoader），定义 batch_size=16\n",
    "dataset = TensorDataset(x_tensor, y_tensor)\n",
    "print(x[:16])\n",
    "print(y[:16])\n",
    "dataset[:16]"
   ],
   "id": "4c0bbaf2f3358a54"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T13:15:26.726371Z",
     "start_time": "2025-06-18T13:15:26.722669Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([0.0600, 0.0700, 0.7600, 0.3600, 0.0400])\n",
      "tensor([2.3570, 2.3916, 8.7871, 5.0476, 2.0751])\n"
     ]
    }
   ],
   "execution_count": 43,
   "source": [
    "dataloader = DataLoader(dataset, batch_size=5, shuffle=True)\n",
    "for x_batch, y_batch in dataloader:\n",
    "    print(x_batch)\n",
    "    print(y_batch)\n",
    "    break"
   ],
   "id": "f91a81e32aacb8be"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-18T13:19:48.220492Z",
     "start_time": "2025-06-18T13:19:47.833649Z"
    }
   },
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGdCAYAAACyzRGfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOehJREFUeJzt3Ql8FPX9//FPEkk4/iRcxRBBgyAgguKFclTF4sllrfVCpLbVqlgrthpRUSwqws8qPRTFWqUe8GgVBEGxIiKisaiIgihnODyC5Uo4AyT7f3xGJu4xszuzO3u/no9HGndmsjtdjn3z+X6/n2+Oz+fzCQAAQILkJuqFAAAAFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAk1GGSYurq6uSbb76Rpk2bSk5OTrJvBwAAOKA9S3fu3CklJSWSm5ubXuFDg0e7du2SfRsAACAKmzZtkrZt26ZX+NCKh3nzhYWFyb4dAADgQHV1tVE8MD/H0yp8mEMtGjwIHwAApBcnUyaYcAoAABKK8AEAABKK8AEAABKK8AEAAFI7fCxcuFAGDRpkrOPVSSWvvPJK/bkDBw5IWVmZdO/eXZo0aWJcc/XVVxvLZwEAAKIKH7t375YTTjhBHnvssZBze/bskSVLlsjo0aON79OnT5eVK1fK4MGDebcBAIAhx6ctyaKklY8ZM2bIRRddZHvNhx9+KD179pQNGzbIkUce6WidcFFRkVRVVbHUFgCANOHm8zvufT70JjSkNGvWzPJ8TU2N8eV/8wAAIHPFdcLpvn37jDkgV1xxhW0KGjdunJGUzC9aqwMAEB+1dT4pX7tVZi792viuj5MhbpUPnXx66aWXGhvNTJo0yfa6UaNGya233hrSnhUAAHhn7vJv5b5XV8i3Vfvqj7Upaij3Duoq53drI2lf+TCDh87zePPNN8OO/RQUFNS3UqelOgAA8QkeNzy/JCB4qMqqfcZxPZ/W4cMMHqtXr5Z58+ZJy5YtvX4JAADgkA6taMXDaoDFPKbnEzkE43rYZdeuXbJmzZr6xxUVFbJ06VJp0aKFtGnTRi655BJjme3s2bOltrZWKisrjev0fH5+vrd3DwAAwlpcsS2k4uFPI4ee1+t6dWiZmuHjo48+kn79+tU/NudrDB8+XMaMGSOzZs0yHvfo0SPg595++20566yzYr9jAADg2Hc793l6XVLChwaIcK1BYmgbAgAAPNa6aUNPr/MCe7sAAJDBerZvYaxqybE5r8f1vF6XKIQPAAAyWF5ujrGc1m5cQo/reb0uUQgfAAAgoQgfAABkwVJbOzlJWGpL+AAAIIMtdrHUNlHivrEcAADwVm2dzwgLujxWV6noZFG7ORsZsdQWAACkzx4trYOW0JZUfydbGxVJTYOCsNfFE+EDAIA026PFF3Tc3KNl0lUnhQQQc6nt9i1V8uUjP6s/Xlo22/iu9ZJiltoCAACv9mjR4Zind34QEDxM5kBNopfaUvkAACCT92jJyZGuQdeW3v6q8b04zHBNPBE+AABIA9+5nThaUSFy9NEB5+p+8xv5720PyJ8dTFSNJ8IHAACZtkfLz38u8tJLgSe++UZy27SRXpJ8hA8AANLAyUc1Fy1ShOsFlid10qtjq9ATKbbpKxNOAQBIAx9v2B42eJy57mNZO35w4MHnnku54KGofAAAkOZzPlY+fJEU1B4MPLh/v0iDBpKKqHwAAJCmcz6a1uyW9eMHBgSPnSec/H21I0WDhyJ8AACQANp/o3ztVpm59Gvju9uN3MxmYebalJvfmyrLJl4WcM2w3z4pjZd8KKmOYRcAAFKsJboVXRKr12snU612BGtfNtvocJqMpbNuUfkAACABLdGDG4RVHmqJruedOv/tl6QiKHj8uffl0uvBeZat1VMVlQ8AAJLYEv2Ol5dJ04YN5PSjW4avWuSEnntr+gLpeXw3uSlJzcKiRfgAACBJLdHVjr0HZOjf/2s/DLNnj0iTJhLC55OfSHpi2AUAgCS3RLcdhunUKTR4nHtuSvbucIPKBwAASW6JrjRO6MCJDtOc07VY8vIs6gMp3LvDDSofAADESfDyWCcB5PAvPrUOHineu8MNwgcAAHFiLo9VTgLI+vED5ZXnfh94cNq0tB9mCcawCwAAcaQTSHUZbHCfjwA+n6yfMMjyuN0qGp3MqnNKdGhHKyysdgEAAAEB5Owuh8uU9yvk0XmrZc/+2vpzd85/Wq77cIbj4OFFw7JkI3wAABBnVoFBWXUqffutJdLv7BMlXMMyn81KmXRpNMacDwAAEtzh9Ee7tlkGj7nLvrENHk4alul5t3vGJAPhAwCAOLEKDOvHD5QPH7s64Lqpx58rpz/wZkwNy/Q19Lxel+oYdgEAwCG3Ez2DA4NVtaP09leN1uk51TVhh06cNixz09gsWQgfAAA4EM1ETzMI/OKjWTLmrckh50vLZts3GQsKNU4blrlpbJYshA8AACKIdqKnBgGrascvf3aPzO/YM+zQSa8OLS0blulrWs3q0KhSXPR9NSbVMecDAIAwop7oefCg9OrYyrLaMd8ieEQaOgnXsMx8rOfTod8H4QMAAK8nehYWWrZC9x9miWboxGxYphUOf/o4XZbZKoZdAAAIw/VEz5zQysNbiz6Xuxd+KxImxDgdOtGAoXNC6HAKAEAG0qGULTtrHF1bunGVyIltQ0/4fPITETmr17FGYJi3olKefm99yGVuhk70fPCckHRC+AAAwEVX0mAaEyosJpXKlVeKvPBCSGDo1aGlnNq+RchzF6dZi/RYED4AAFknUr8Ou9UtjoNHhF1oz8+AoZNYED4AAFklUr+OcKtb/N0770m55uNXXQePTBk6iQXhAwCQNZz06yhqlB9xqMWqd4e8+65I377e3nCGYqktACArOO3XUVltHzwK9+2yDh5a7SB4OEblAwCQFZz269i2y3p1i2XoEJH2ZbNl0vJvs2KiqFcIHwCArOC0X0eLJvkhbcytgken38+Q/Yc1CLsfC6wx7AIAyApON1wrLmpU38b85vemWu9EWzbbCB7ptpV9qqDyAQDICm42ZtMKhtUS2hldz5KRg/6QtlvZpwrCBwAgK5gbs+mqFg0avnDdRS1apEfalyUdtrJPFQy7AACyRsSN2bqXWAaPXg/OC9lJ1qTH26TJVvapgsoHACBjO5W66i6aZ/Hv8fnzRfr1k3sP9QeJWDGBI4QPAEBGdip13F30s89E8lqF7VRqVkyyeT8WL+X4fA77wCZIdXW1FBUVSVVVlRQWFib7dgAAadSp1Kw9GEMoTgKBxRCLweajMZpKS7aodvH5TeUDAJBRnUod992wCh61tSK59tMhs3k/Fi8x4RQAkJGdSm37bgwcaB08tNoRJnjAO7zLAIC04rSfhuV1GjrmzAk8dvXVjneihTcYdgEApBWn/TQCrjtwQCQ/P/SiCKGDOR7xQfgAAGRsp9JoJpV6sZoG4THsAgBIy06lKjhWOOlUKqtXOwoeupomeG6JPtbjeh4JDB8LFy6UQYMGSUlJieTk5Mgrr7wScF5X7t5zzz3Spk0badSokfTv319W6y80AACJ6lS67kP7SaUdO0a9msZ4ikOrafQ6JGjYZffu3XLCCSfIL3/5S7n44otDzk+YMEH+8pe/yJQpU6R9+/YyevRoOe+882TFihXSsCF97wEA3nDVqVQ5nFQaaTWN+K2mYdltgsLHBRdcYHxZ0arHxIkT5e6775YhQ4YYx/75z3/K4YcfblRILr/88ihvEwAAB3037KodLlRW7fX0OsR5zkdFRYVUVlYaQy0m7XZ22mmnSXl5ueXP1NTUGF3R/L8AAHCleXNPgofatnu/p9chzuFDg4fSSoc/fWyeCzZu3DgjoJhf7dq18/KWAACZTkPHjh2Bxx59NOreHc0a53t6HVJwtcuoUaOMPvDm16ZNm5J9SwCAdLB1q32145Zbon7aHXv2e3od4tzno7i42Pi+efNmY7WLSR/36NHD8mcKCgqMLwBA9nLdzCvK3h1OtPh/BZ5ehziHD13dogHkrbfeqg8bOofjv//9r9xwww1evhQAIEO4buZlFTy2bft+3ocHigsbenodPBh22bVrlyxdutT4MieZ6n9v3LjR6Ptxyy23yP333y+zZs2SZcuWydVXX230BLnooovcvhQAIMPZNfPS7qXXP79E/vjq51K+duv3PTVuv91+mMWj4OHfQTWcNv4dVOFajk/Xx7qwYMEC6devX8jx4cOHy7PPPmsst7333ntl8uTJsmPHDunbt688/vjj0qlTJ0fPr5USnXiq8z8KCwvd3BoAII1ooOg7fn7Enhpq/fiBoQcbNBDZvz+uoUj5f0ia0cdoZEaL9ag/v12Hj3gjfABAdtCKxhVPfRBd8EjARxd7u8Tv85uN5QAASWG55X2k0KEVk9o6yZMkdlBlV9uYET4AAEkRsOW9g+Bxw5A75PUufWVqAtuah3RQhScIHwCApDAndurkUnMQ5bjKNTJnSmiPjtKy2Y4rJkh9hA8AQFJoVUHnT+jETh3IqLAZZvEPHpEqJkgPhA8AQNLovApj5Uj3kpBzHW6bKbW5P8zu0IBSzBLXjED4AAAkT2mpnL9hQ8RqhznFUyslTPhMf0nf2wUAkKW0YVhw8GjXTuYu+yakyZdWPOitkTmofAAAEqp2/wHJK8i37d1xvghLXDMc4QMAkDg5OZY9OrTaoaHDxBLXzMawCwAgMSz2ZRky7E/Svmy2seJFO4oiOxA+AADxNW2aZfDQSaWflnSu7/GhrcyNDeSQ8Rh2AQAE0ADg2XwLq11oLVazaOTQPVT0dRluyXyEDwBAfDZTs6l2hEP30uzAsAsAIGAb+eAt7rX9uas5GRo6oggeiu6l2YHwAQAwhlq04mE148LVnAyrYZYbbjB2otUKit3gjR5vE6F7qb52+dqtMnPp18Z35oekL4ZdAADGXIvgioerORlbt4q0amXxg98HBF1e67+Pi89l91JPh4OQdFQ+AACO51pYXqfVjjDBI3gfF+1W6qZ7qWfDQUgZVD4AAI7nWoRcZzXMUlkpcvjhlj+vAcNN99JIw0H6U3pen5MOqOmDygcAwAgAruZkjBhhHTy02mETPIK7lw7pcYTxPVxocDMchPRB+AAAGAFA50+o4CgQMidDQ8fjj0ccZkn6cBBSFuEDAOB8ToZdtSMOwSOm4SCkNOZ8AAAiz8nIs/m3apxCR/BwkE4utXqlnEPhKNwSXaQeKh8AgPBzMqyCxxNPxD14uB4OQtogfAAArC1daj/M8pvfJOw2ol2ii9TFsAsAwPGGcImodnixRBepjfABAIgcPGpqRPLzJRWGg5D+CB8AkEW0aZdt9eC440RWrEiZagcyF+EDALJE2P1RupeE/kDz5iLbaN4F7xE+ACALmPujBNcwvtu+2zp4UO1AHBE+ACDD2e2Psn78QOsfcBg8wg7hAGEQPgAgw1ntj2IVPJZPmy3dLhvg6DnZ4h6xoM8HAGQ4/31PBn6x0DJ4lJbNlrWdezh6Pra4R6yofABAhjP3PbEbZtHg4X9dOGxxDy8QPgAgw+lcDLtqh9v9UdxscU9PDtghfABAJsvJkTyLw/7Bw83+KGxxDy8w5wMAsqhT6VvdzqgPHtHsj8IW9/AClQ8AyDTbt4u0sBhC8fnkrDqfTI1heSxb3MMLhA8AyKIN4WLdH8Xc4l5Xtegr+QcQtriHUwy7AEAmB4+NGz3vVsoW94gVlQ8ASHdlZSITJiS0RTpb3CMWhA8AyOBhlnhii3tEi/ABACnE1X4pVsGDDeGQBggfAJAi7PZLGT2gqzRvkl8fSHp1bGX9BEHBg43fkKoIHwCQwlveaxC58cUl9Y+tOpXW/elPknvrrSHPx8ZvSFWsdgGAJAu3X4qp8//W27ZI71NzQsBmbmz8hlRH+ACAJIu0X4qGjjf+cVPIcbNTqX+oiLTxm9Lzeh2QLAy7AECShdsHxara0fnWl6WmQYHlbrJNCxqw8RtSHuEDAJLMah+URZOukbbV/ws57r8vi1WoKF+3xdFrsvEbkonwAQBJpqtQmjVuIDv2HLCtdoQLHoGcrWZh4zckE+EDAFJEjq9OKiYMjjJ0fE+HUl5e8hUbvyGlMeEUAJJM518svfe8mIJHzqGltKcf3dJYThsOG78h2QgfAJBkVk3DrvvpXa6Ch3+o0D4e153RXoLzhT7W4/T5QLIx7AIAMYq6k+hzz4lcfXXIYbvQcVO/DtIgL0+mLt4oldU/TBgtDmoepktuJy+sCBl20QaoevzEI5sTQJBUhA8AiEHUnURtNoSzCh7mPI2R53Q2Qs1NZ3e0DTuR+nyYS3J1R1qGXpAsDLsAQJSi7iRqETzmfva1tC+bHbJWJXhIxX832SE9jjC++4eISA3L/Pt8AMlC+ACAKETVSVRDh81OtOd3L5FJV51kVDj86WM97nSYxGn/Dvp8IJkYdgGAKLipMBidRK1CR+fOIl9+Wf9QA8bZXQ6X58rXy4Zte+SoFo1lWK9SyT/M+b8TnfbvoM8HMqryUVtbK6NHj5b27dtLo0aNpEOHDjJ27FjxBW31DADpSCsZ5Wu3yusON2fb9s1m22qHf/BQOkxz5v+9LWPnfCH/LN9gfNfHbjaC0/kfOuckJ8KSXPp8IKMqH+PHj5dJkybJlClT5LjjjpOPPvpIrrnmGikqKpKbb77Z65cDgKROLg3H6FQ63uKExT/GzPkjwWfM+SNOh150/ofOD9Gf0aDhizB/BMiIysf7778vQ4YMkQEDBkhpaalccsklcu6558rixYu9fikASPrkUjuWLdK/+MIyeHi9E62GFC/mjwBpU/no3bu3TJ48WVatWiWdOnWSTz/9VBYtWiSPPPKI5fU1NTXGl6m6utrrWwKAmIQLB8EenPs3ufLTuaEnwgw9u54/4oAGDF1OG1X/ESDdwscdd9xhBIguXbpIXl6eMQfkgQcekKFDh1peP27cOLnvvvu8vg0A8EykcGCy2xAuXPCI5woVc0kukPHDLv/617/khRdekBdffFGWLFlizP14+OGHje9WRo0aJVVVVfVfmzZt8vqWACAmTj70LYOHhg4Hk+1ZoYJs43nl47bbbjOqH5dffrnxuHv37rJhwwajwjF8+PCQ6wsKCowvAEhV4T70o612WK1QYSdaZAvPKx979uyR3NzAp9Xhl7q6Oq9fCgBiXjI7c+nXxvdwkzntlq9aBo/f/c5V8PBfoaKcdDgF0p3nlY9BgwYZczyOPPJIY6ntJ598Ykw2/eUvf+n1SwFAVBu/bd+9X8bOcb4fi//yVdXluwqZ+8xvQ18oTOiItPmcuUIleClv8KZxQCbI8Xnc/Wvnzp1Gk7EZM2bId999JyUlJXLFFVfIPffcI/n5+RF/Xierak8Qnf9RWFjo5a0ByEJOe3OYPTFG9j9GSls1sQwI415bIaMGHGf9BGH+KnWz+VzUO+QCSebm89vz8BErwgcAr9g17nKquLBAruh5pBFG1m/ZLb87p3PINd1v+ZfsKmhs2z/D7h7MOEHfDWQKN5/fbCwHQLK9N4edyuoaeXTeajn5zBMtg0dp2WzZWdDYtgmY183DgExB+ACQ1b05ItFJpW2r/2cZPCJtU8/29oA1drUFkJFi3jLe55P1EwaFDR2RXpPt7QFrhA8AGSmWhlx2vTvCBQ+r16R5GGCNYRcAGSnS1vJugsfIAbeGDR5229SzvT1gjfABICOFa9xl5eLlb1kGDw0dM7qdbftz4ZqA0TwMsEb4AJCx7LaWD6ah45E5j7oeZnGyTT3b2wOh6PMBIOOZjbsqq/bK6Jmfy66ag/XnLKsdt78qkpNj24jskpPaSuOCPDmqRWMZ1qtU8g+L/O84moch01XTZAwArGnTr+ufX2I7qfTPb66S0laNZf2WPTJ18UaprP5hJUqzxg2M7zv2HHDUlh3IJtWEDwAIw6KqUZuTK29+9lVAiPCvVmgYmThvFZ1KARt0OAUAK1VVlsFD53b0uf+NkOM6LNKrQ0sZeHyJTPtwo22nUv2iUyngHOEDQNrQD/fytVtl5tKvje+uPuw1dDRrZjupdHN1jbEHiw7LRNMtlU6lgHM0GQOQFtzsDBvCotpx0bA/ydKSH/Zr0RijV+lrnNO1OGAyqP+8j3CcXgdkOyofAFKeuTNscPWhsmqfMXn0z/NWWVdDhgyxHWbxDx6R9lrZsrPG0X06vQ7IdlQ+AKQ0JzvD6s6zIdWQ7iWWz+ekd0fwXivb9+x3dK9OrwOyHZUPABm1O61WQyyDh88n5Wu2RLXXitN2HLTtAJwhfABIaW52fNXeHRVW/TsOdRSIdq+VXke3cvT6Tq8Dsh3hA0BKa9WkwNF1Vk3Ddp54an3wiGWvldM7tKxvMGZHz+t1ACIjfABIbRGGMrpVrrHdEG7+P2Z4steKhpGHLu4e9j70PO3SAWeYcAogpW3ZZb+CxK5FujmpNHjuhkkDhi6ndbPXiv7ME1edJGNmfS6V1T/cU3FhgYwZfBzdTQEXCB8AUppdgLAKHiff9LxsbdLMKJYUW8zdsOpe6kY0oQVAKMIHgJRmThLVVSw+B9UOq7kbXu4oG01oARCI8AEgpZmTRLXJWKTgIYcqHv5dT2PqjAogLtjVFoBnnFYYXFci9K+p3ND58b0enCd3XXCsbN65TzZs2yNHtWgsw3qVSv5huQGdUdmJFkitz28qHwA84bTC4LoSYdEeXWnDsNG7a2TsnC8CnuvviyqM59K5GeE6o9rt4wIg/lhqCyCue6/47xTr9LqwwWPUKKMSUrV3v4x48RPb5/rb/NVhO6Pa7eMCIP4IHwDivveKnt9/sM7RdcbGcJMmWQcPHX558EFHr/nMe+s976AKwBsMuwCI694rZoXhufL1jq7Ly7P5N5Hf9DQnr7lj7wFPO6gC8A6VDwAxcVo50AmhkViuZjl4MCB4uHlNR5juASQclQ8AcWkCFkxXotixW0IbHDrcvmasHVQBxAeVDwAxcbpTrC6BtbrObfBw+potmoTfCC4eQQaAM4QPAI7oJM/ytVtl5tKvje/GxFAXO8Vq7w3/65rU7LEOHho6IrQfcvKa9w/p5igUhWvBDiA+aDIGICInvTnc9Pk4v3uJ9Qu5/Oso0muaS3uNp/b7OZqMAcn9/CZ8AAjLTZdQR51LLZbQ1r72uuRdcH5U9xfpNWmvDiQG4QOAJ/SDve/4+bbLWs3dYxeVnR25S+gll4i8/HLo8QT8FeTlxnIArNFeHUBCe3jodWF3erVpkZ6I4KHYiRZILYQPALac9tMIe51dp1IAWYvwASDmZaiW1yW52gEgdbHUFkDMPTxClqtaBY8OHQgeAAyEDwAR+2nYRQY9rufrJ29+/rn9MMuaNRF7hgDIDgy7APCGw2EWXfo6ZtYKqaz+YZ5IcWFDGTOYpa9AtqDyAcCWuXW9HY0bxnmr4PHVV5bB4/rnlwQED6WP9bieB5D5qHwAiHqpbYWLfVk0yNwxfVnY1xs1fZmc07WYHhxAhqPyASCqJbRuN4T7YN1W2bHnQNjX277ngHEdgMxG+AAQwpwQunrzLsvz0WwIp8/nhNPrAKQvhl0ABLDaCyVStaO2tk7yIj6z0xUtrHwBMh2VDwAhm8g5DR5P9rxY5i77xtEcjV5Ht3J0D06vA5C+CB8AAla2BNcdBq9YYBk8ej04T456+m+Ol8ee3qGlNGvcIOw1el6vA5DZGHYBYLuyxW6YpXzNFlnkcmdYvfahi7sbS2rt6HlWugCZj8oHAMuVLVbBo+MfXpGZn3xl7BBLSAAQLSofAAI2h7OrdpSWzQ64Ll4Ny+jzAWQ+Kh9Ahoh1v5STj2oeMXhoJtDr4tGwTO9Wz+t1ADIblQ8gQ5fH6m6zuumbowmhe/dKfuPGtqHDpHnm4w3bjWEXLxuWRXMdgPRF5QPI0OWxlVX7jOMR90vRfVkcBI9Yw4HT4Zpoh3UApA/CB5CBy2OVeUzP2w7BWGwI96ufjbYNHrGEg57tWxjVGLvZHHpcz+t1ADIb4QNIY1HPoxg+3DJ4aO+O+R1Pi0s40EmkOgxkPlfwcys9z2RTIPPFJXx8/fXXctVVV0nLli2lUaNG0r17d/noo4/i8VJAVk8mjWoehYaOf/4z9CKfL2w40Fe8/NR2Mvuzb6Ka0Kp0/smkq06S4qLA6ok+1uNOG5YBSG+eTzjdvn279OnTR/r16yevv/66/OhHP5LVq1dL8+bRzZAHsl24yaSu51FYVDv8N4Mzw0Hw6xUd6kz66LzVIffgNjDo9bqcVqsxGor03rSaQsUDyB45Pl+YbSijcMcdd8h7770n7777blQ/X11dLUVFRVJVVSWFhYVe3hqQtpNJg/+Qmh/Tj115ooyd84UxudTqD3LOoapC+Z39rV/A5o+/VjXMcLB+yx6ZOG+V7T1QsQDg9vPb82GXWbNmySmnnCI///nPpXXr1nLiiSfKU089ZXt9TU2NccP+XwCcTSbV4DF6QPh5FJbBo6jINngorULoctqBx5fItA83Rj+hFQASET7WrVsnkyZNkmOOOUbeeOMNueGGG+Tmm2+WKVOmWF4/btw4IymZX+3atfP6loCMnkzavEm+5TyKk2q3SYVV0zANHTt2eHoPNAYDkNQ5H3V1dUbl48EHHzQea+Vj+fLl8sQTT8hwnWEfZNSoUXLrrbfWP9bKBwEEcDeZdEiPIwLmUQw5sa3ltbW1dbJ47VbHcy1oDAYgLcJHmzZtpGvX78vApmOPPVZefvlly+sLCgqMLwCB3E4mNYdKLCeVVlTI3F0Fct/4+a66oNIYDEBaDLvoSpeVK1cGHFu1apUcddRRXr8UkNF7r7huylVSYruaRYNHNF1QaQwGIC0qHyNHjpTevXsbwy6XXnqpLF68WCZPnmx8Adkqmr1XzKZcGg7MPhu2TbmsQofy+SJOXA23m6yrewCAZFU+Tj31VJkxY4ZMnTpVunXrJmPHjpWJEyfK0KFDvX4pIOP3XnHUlMuud8eh1SyxThqlMRiAtNjVduDAgcYXkO1iqTpEbMqVZ/Nvh6AltF5MGqUxGICUDx8AxHXVIdw29fWTSU1W1Y6RI0UeeSRuk0ZD7gEAokT4AOLI86Wqc+ZoaTH0eJiGYeak0UhdUJk0CiBR2NUWiCNPl6pqtcNl8DDbpF/Qrbh+mCfgKQ99Z9IogESi8gHEkWdVB6thln37tFGOqxU2+jT+WaU4ys3hACAWhA8gjsylqtc/v8TyvC9S1SHMEtpoNqQzW4v8qk+p9O9azKRRAEnBsAuQZCsrd1k3HosyeIRbYWN6bXklwQNA0lD5AOLIDALhPDpvVf1/6xDNmPOPkfNOOsp16HC6wkYcrrABgHghfABx5CQI+Cu/s7/InRJ18FCV1fs8vQ4AvMawCxBHbnZ7XT/eYiWLbsjoIniobbtqPL0OALxG5QOIIydLaEe++7z87v1pIcfL12yJalikRZN8T68DAK8RPoAkLrW1rHaISGnZbPmzi6qJv+KiRp5eBwBeY9gFSMBSW5XjIHho6NAvNw3K7AJPOHqejqYAkoXwAcRZ8K6wGjrsgoepRZMGxoTQkOW3LgKP3SJaPU5HUwDJlOPzuZzNFmfV1dVSVFQkVVVVUlhYmOzbATyjIcJqJ9q1LY6Qn1z7ZNgqRTRdSK06nEb7XADg5ec34QNIhG+/FSkpCTnc68F5EZfimvUJrZ64DQ3m3i666kaHcWgsBiAVPr+ZcAq45PoDPUyn0kWHnquyaq+MnfOFbNu9P/SyQwFEqxjndC12FR70WhqJAUg1hA8gnkMZVsFj7VqRo48OCAc6t8MqePgHELqSAsgUTDgFHDI3awseJtFltHpcz9c76yzr4KGjnIeCRzTNyNw0LQOAVEX4ABwIt1mbeUzPGytTNHS8847FhfbTq5wuq412+S0ApBLCB+DBHi3msIjVahYjdESY133yUc0l0lQOPa/XAUC6Y84H4MFwh12nUqf7sny8YbtEaueh5/U65nwASHdUPoAYhzusgkfd73/vakM45nwAyCaED8BFy3L/kZGTvvrCtlNpn5YXBE5AjYA5HwCyCeEDiGKPFg0d01+4zbZFuuUKGJfhxp8eZz8WAJmC8AG43KOlwqLa0fn30wP2ZglZARPDBnTmY/ZjAZApCB+AUy1byvndQ1uka+ioOSw/bGMwOxpMtMHYzKVfS1GjfHnsyh82oDPp42haqwNAqmK1C+CETYt0/2qH20midt1SRw84Vpo3KWA/FgAZi8oHEE5trW2n0vI1W6KeJBquW+qIFz+Rqr37ZUiPI4xltQQPAJmG8AHY0dBxmEVx8NAS2mgnibrqlgoAGYjwAVixqnb85z8BvTuinSTqtFtquLkiAJDOCB/IOP6TOPW7qwrCs8/abwh3zjm2K2DcTBKloRiAbMeEU2T3lvcOJpVG6lSqz3tO12KjUuFkkigNxQBkO8IH0opWMew+5M1JnMFRwWz4FXa5qlXwqKuzDyRB9B6c7rlizhXR+7KKNTmHKic0FAOQqQgfyIiqhlYewk3i1A90Pa/XBVQkoqx2xMKcK6KBSF/d/5VoKAYgGzDnA2kh3NJUPf63+avdT+K0Ch5nnBHX4BHLXBEAyBRUPpDyIi1N1QjxzHvrnU/i3LbN6FYa+mSJXdrqdq4IAGQKwgdSnpOlqTv2HnD0XENObGvzJMnpqeFmrggAZAqGXZDynC45bdaoQdiGX7oTbYh165IWPAAgWxE+kPKcLjnVCoJVjBg396+WO9EaoaN9+9hvEADgCsMuSHmRlqaaXl9eaXzXKRNmXzHLaoeKodoRbrkvACAywgdSXrilqeFyhWXwiHGIJaYmZgAAA8MuSAt2S1Ot6BBLvIJHuOW+eh4AEBnhA2kVQBaVnS1Trz1dburXwfIay9Bxzz0xBw92ogUA7xA+kFbMpanHHN404Pgx/9tgGTxmfvKVyH33xfy67EQLAN5hzgfSfgWM3aTS0rLZMtWjzdnYiRYAvEP4QFLEumLEXAFTfmf/kHNdbn1Jaho0NM57tTkbO9ECgHcIH0g4L1aM5PXtI+Xl5ZbVjnhszsZOtADgHeZ8IKE8WTGiG8LZBI94bc5mLvc1Xj74dg59ZydaAHAmx+dLrd7S1dXVUlRUJFVVVVJYWJjs24HHQy19x8+3nbhpVg90RYvlh7j+Vs0Nzcu1tXUJa/pFnw8AiP3zm2EXJIybFSMhm61ptcPyh3ySd6i1eiKwEy0AxI7wgYSJesWIVfCYP1+kXz9JBnaiBYDYMOcDCeN6xcjcudbBQ4dfkhQ8AACxo/KBhHG1YsRmmMWY37F2K0MeAJDGCB9IiQ3iAlaM5FkU5OrqZO7nlXJf0IRVJnsCQPph2AUpsUGcPl43YZCc370k9Id8PiN4sKkbAGQGKh9IOKsVI706tgq98Kc/FZk+PeKmblo10fP6nAzBAEDqI3wguStGdu0SaRq4SZzBr/1MTEt0AQDZN+zy0EMPSU5Ojtxyyy3xfimkG51UGiF4KDZ1A4DMEtfw8eGHH8qTTz4pxx9/fDxfBunIajXLunUhwUOxqRsAZJa4hY9du3bJ0KFD5amnnpLmzZvH62WQbv7yF/veHe3bh12iazebQ497uYMtACBNw8eIESNkwIAB0r9/6Jbn/mpqaox+8P5fyFAaOn73u9DjEbYXYlM3AMgscQkf06ZNkyVLlsi4ceMiXqvX6EY05le7du3icUtINrtqh8N9DcMt0fV6B1sAQJrtartp0yY55ZRT5M0336yf63HWWWdJjx49ZOLEiZaVD/0yaeVDAwi72maIMBvCRUOX3bKpGwCk9662noePV155RX76059KXp7uNfq92tpaY8VLbm6uETT8z8Vy80jD4KFzPn7722TcDQAgjtx8fnve5+MnP/mJLFu2LODYNddcI126dJGysrKwwQMZYsMGkdLS0OPe5lwAQJryPHw0bdpUunXrFnCsSZMm0rJly5DjyEAeD7MAADIPe7sgvsFDO5gSPAAAiW6vvmDBgkS8DJJl2DCR558PPU7oAABYYG8XeF/taNlSZMuWZNwNACANED4QHa1q5FqM2lHtAABEQPiAe0wqBQDEgAmniD14vPUWwQMA4BiVDzhTXi7Su3focUIHAMAlwgciY5gFAOAhhl3gPnjU1RE8AABRI3zA2gkn2O9Ea1cJAQDAAcIHQmm4+OyzwGPXXEO1AwDgCeZ8oH6b+i1bdsig0zuGXkDoAAB4iPCR5eYu/1bue3WFlN/Z3/oCggcAwGMMu2R58Ljh+SWWwaPv9U/L3GXfRFVFKV+7VWYu/dr4ro8BAPBH5SNLaSj48L6JUvHShJBzpWWzRaeUakXknK7Fkpeb46qK8m3VvvpjbYoayr2Dusr53dp4ev8AgPRF5SNL5eXlymib4KG0XqEhQueCuKmi+AcPVVm1zziu5wEAUFQ+spHFUlkzdAT7bmdgmLCromjFw2qARY9FU0UBAGQuKh/ZFjpcBA/VumnDiE+r1ZHgioc/t1UUAEBmo/KRLSxCx58GjpC/HXeB9eUiUlzUUHq2bxHxqZ1UR9xcBwDIbFQ+Mt3mzbadSo8bd5fxn8Fnzcc6UdTJMImT6oib6wAAmY3wkck0dBQX2/bu0BUok646yahw+NPHejx4hYrdMlqtjuiqFruYosfbOKyiAAAyH8MuKdxxVIcptFqgH9quJ2paVTuqq0WaNg04pAFDJ4JGer1Iy2j1u65q0Z/yxVBFAQBkvhyfL7VaWFZXV0tRUZFUVVVJYWGhZFvQ2L57v/xx9gqprP7hQ764sKGMGeywV8ZDD4mMGhV6PIZfZnMZbfAzmFHCrJLQ5wMAsle1i89vwkcSWX1Yh/OExVBIxGpH374i774bUzjqO36+7T2aE1MXlZ1tVDY8qdoAANKOm89vhl2SxK6aEM6o6cuse2Vofsy1mL7jQa50s4y2V4eWxr3pdwAA7DDhNAnCNeUKZ/ueA/LBuq2h1Y44BQ/FMloAgNcIH0kQqZoQjq4yCTvMsnixpzvRsowWAOA1wkcSxFYl8ImsXGnbu0NOPVW8xDJaAIDXCB9JEEuV4A/nHyvSpUvoiTjNG9Y5HLpaxYtmZAAAKMJHEkSqJthZP35g6MHa2rgFD5PbZmQAAITDUts4ibTk1FztoiL9Ajzwxt9k6NK5oScS/EvHMloAgB36fCSZ02ZbVtc1b9xA6nw+qdp70L7acffdImPHOrqX/Qfr5Lny9bJh2x45qkVjGdarVPIPo+AFAPAW4SOJnHYDDVdNUB+u2iynH2sxnOHil2vcayvkqXcr5NAWLAYtVFz74/Yy6sLv53EAAOAFmoylYP8O36EAouf9G4VZNuXKyZHTrV7AZfB4cmFFyHENIuZxAggAIBmov3vITTdQW1ZLaDdudBU8dKhl8ruhwcOfntfrAABINMKHh2LqBqrNwex6d7Rr5+o+pry/PmJW0fN6HQAAiUb48FDU3UA1dJx2WuiGcFFOx/lw/TZPrwMAwEvM+YhD/47Kqn2W8z7MHWADuoHaVTti0Dg/z9PrAADwEpWPZHUDHTnS8+ChE1517xcNQE787MS2Ub8WAADRovIRp26gY2atkMrqH+Z2FPv3+bAKHQsWiJx5ZtSva9UzJFLVo/cxraJ+PQAAokX4iFsHz8AKhrZTyd27Jy7DLHa9RcJ55NIT6E4KAEgKwofLrqTRBoF37rlACu76vmupl8EjXG8RK4c3zZf7hnRjPxYAQNIQPsIEBp04qsedbp5mFwQsW6Tv3SvSMPrdbZ32FjHd1K+D9On4I/ZjAQAkXdZPOI3UlVTpeb3ObRDouWm5ZfAoX7PFk+DhprfIMYc3NTqpEjwAAMmW9ZUPN11JQ9qghwkCVqHjj2dfK/84dYj82WFgiGtvEQAAkiTrw4fTysHry781vocbtjA/4K2CR2nZ7JDrktZbBACAJMr6YRenQeCf5Rvkiqc+kL7j5xtzRKyc9syjYYOHBoE2HgcBV71FAABIAVkfPszKgVPmJNSQAJKTI7kPPBBwqNcNzwQEj3gFAbO3iFY4/Oljp5NlAQBIlKwfdtEgMPiENpbbz1vRoY2cQ5NQz+laLHk7q0WaNQu57vQH3pTK6hrrJmNxoM+r9+NdnxIAAOIj68OHrmKZ9an1MEqkSah7TzxZ/t9nnwSc+8fJg+WP/a+TYsmRkf07SWmrxvVBQGn783iFA32uSJNiAQBItqwPH077ZASznNtx+6v1HUw3V++TifNWGcMeGgi8amIGAEC6y/o5H05Xu5hO+epz+0mlfq3T/XuEvPbZ903MgkOO7fwRAAAyWNZXPtwse7UKHRcN+5MsLekcdnjm7pnLbZuYBcwfYX4GACALZH3lw1ztEu5jP8dXZxk8Zn7ylW3w8Ldt935HTcwAAMgGudk0sVQne85c+rXx3WyXHq5PhrrtnSlSMWFwwLFtJ/U0NoTzslmY2+EfAADSVVYMu+icijGzPg9c+lpYIGMGH2dM9jT7ZARPCLWqdtTuqJIWRYWOu4s2b9JAtu0+EPEeaX8OAMgWudkQPK5/fklA8FD6+Hq/yZ4aQBaVnS1Trz1dnvhJG+udaH0+yTsUPJx2F71/SLewwzrx6HoKAEAqy+jwoUMrd0xfFvaaP/z7U5nxyfdDMarXwL5y/rknB140ebIRPKLpLnrh8SW0PwcAwE+Oz2fzqZok1dXVUlRUJFVVVVJY+EOVIRrvrd4iQ5/+r+Pr7aodToNOuO6i9PkAAGSyahef357P+Rg3bpxMnz5dvvzyS2nUqJH07t1bxo8fL507R14V4rXydVsc9+546YWy0BMuclmk7qK0PwcAIE7h45133pERI0bIqaeeKgcPHpQ777xTzj33XFmxYoU0adJEEisnqmrHkNtflOnjLpc8j++G9ucAAMQhfMydOzfg8bPPPiutW7eWjz/+WM444wxJJP2g/9vbayzP5dbVyrr/GxJy3NyFVisUBAUAANJwwqmO/agWLaxXc9TU1BjjRP5fXjn96JbSrHGDkOPnrXo/JHhMOOPq+uCh6LsBAEAa9vmoq6uTW265Rfr06SPdunWznSNy3333xeX1dZjjoYu7G0tqww2zHH3bTKnLDRxkoe8GAABpWPnQuR/Lly+XadOm2V4zatQoozpifm3atMnTe9CJnk/oUtjChiHB4532JxnVDv/gQd8NAADStPJx0003yezZs2XhwoXStm1b2+sKCgqMr3gyVpoUHhS564djZ//6CaloGXhf9N0AACANKx/aNkSDx4wZM2T+/PnSvn17SQV5R7YTueQSkX79jCW0t/9usG1jMPpuAACQRk3GbrzxRnnxxRdl5syZAb09tPGI9v1IZJOxWBuDAQAAZ9x8fnsePnJyrD+8n3nmGfnFL36RUuEDAABkQIfTFOvWDgAAUkxGbywHAABSD+EDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAkFOEDAAAklOd7u3i1N4xuUAMAANKD+bntZI+3lAsfO3fuNL63a9cu2bcCAACi+BzX3W3DyfGl2Da0dXV18s0330jTpk0lJyfHSFIaRDZt2hRxi154i/c+eXjvk4f3Pnl479P7vdc4ocGjpKREcnNz06vyoTfctm3bkOP6ZvCbMTl475OH9z55eO+Th/c+fd/7SBUPExNOAQBAQhE+AABAQqV8+CgoKJB7773X+I7E4r1PHt775OG9Tx7e++x571NuwikAAMhsKV/5AAAAmYXwAQAAEorwAQAAEorwAQAAsi98PPbYY1JaWioNGzaU0047TRYvXhz2+n//+9/SpUsX4/ru3bvLa6+9lrB7zTRu3vunnnpKfvzjH0vz5s2Nr/79+0f8tYJ3v+9N06ZNM7r/XnTRRXG/x0zl9r3fsWOHjBgxQtq0aWOsBujUqRN/7yTgfZ84caJ07txZGjVqZHTfHDlypOzbty9h95spFi5cKIMGDTI6j+rfHa+88krEn1mwYIGcdNJJxu/3jh07yrPPPuvtTfmSbNq0ab78/HzfP/7xD9/nn3/uu/baa33NmjXzbd682fL69957z5eXl+ebMGGCb8WKFb67777b16BBA9+yZcsSfu/pzu17f+WVV/oee+wx3yeffOL74osvfL/4xS98RUVFvq+++irh955t772poqLCd8QRR/h+/OMf+4YMGZKw+83m976mpsZ3yimn+C688ELfokWLjF+DBQsW+JYuXZrwe8+m9/2FF17wFRQUGN/1PX/jjTd8bdq08Y0cOTLh957uXnvtNd9dd93lmz59uq5u9c2YMSPs9evWrfM1btzYd+uttxqfs3/961+Nz925c+d6dk9JDx89e/b0jRgxov5xbW2tr6SkxDdu3DjL6y+99FLfgAEDAo6ddtppvt/85jdxv9dM4/a9D3bw4EFf06ZNfVOmTInjXWamaN57fb979+7t+/vf/+4bPnw44SNB7/2kSZN8Rx99tG///v0JvMvM4/Z912vPPvvsgGP6YdinT5+432smEwfh4/bbb/cdd9xxAccuu+wy33nnnefZfSR12GX//v3y8ccfG+V7/71d9HF5ebnlz+hx/+vVeeedZ3s9vHvvg+3Zs0cOHDggLVq0iOOdZp5o3/s//vGP0rp1a/nVr36VoDvNPNG897NmzZJevXoZwy6HH364dOvWTR588EGpra1N4J1n3/veu3dv42fMoZl169YZQ10XXnhhwu47W5Un4HM2qRvLbdmyxfgDrH+g/enjL7/80vJnKisrLa/X44jvex+srKzMGEMM/k0K79/7RYsWydNPPy1Lly5N0F1mpmjee/3Qmz9/vgwdOtT48FuzZo3ceOONRvDWjpCIz/t+5ZVXGj/Xt29fY7fUgwcPyvXXXy933nlngu46e1XafM7qzrd79+415uBkxIRTpJ+HHnrImPg4Y8YMY/IY4ke3qB42bJgx4bdVq1bJvp2sU1dXZ1ScJk+eLCeffLJcdtllctddd8kTTzyR7FvLaDrhUStMjz/+uCxZskSmT58uc+bMkbFjxyb71pDulQ/9izQvL082b94ccFwfFxcXW/6MHndzPbx7700PP/ywET7mzZsnxx9/fJzvNPO4fe/Xrl0r69evN2ar+38gqsMOO0xWrlwpHTp0SMCdZ+fve13h0qBBA+PnTMcee6zxr0MdTsjPz4/7fWfj+z569GgjdP/61782HuvKxt27d8t1111nhD8dtkF82H3OFhYWelL1UEn91dM/tPovibfeeivgL1V9rGOsVvS4//XqzTfftL0e3r33asKECca/PObOnSunnHJKgu42u997XVa+bNkyY8jF/Bo8eLD069fP+G9dgoj4/b7v06ePMdRiBj61atUqI5QQPOL3vuucsuCAYQZAtiSLr4R8zvpSYPmVLqd69tlnjSU91113nbH8qrKy0jg/bNgw3x133BGw1Pawww7zPfzww8Zyz3vvvZeltgl67x966CFjqdxLL73k+/bbb+u/du7cmcT/F9nx3gdjtUvi3vuNGzcaq7puuukm38qVK32zZ8/2tW7d2nf//fcn8f9F5r/v+ne7vu9Tp041ln7+5z//8XXo0MFY8Qh39O9obZGgX/qx/8gjjxj/vWHDBuO8vu/6/gcvtb3tttuMz1ltsZBxS22VriE+8sgjjQ82XY71wQcf1J8788wzjb9o/f3rX//yderUybhelwPNmTMnCXedGdy890cddZTxGzf4S/+SQPx/3/sjfCT2vX///feNJf364anLbh944AFj6TPi974fOHDAN2bMGCNwNGzY0NeuXTvfjTfe6Nu+fXuS7j59vf3225Z/d5vvt37X9z/4Z3r06GH8Wunv+WeeecbTe8rR//GujgIAABAeM3YAAEBCET4AAEBCET4AAEBCET4AAEBCET4AAEBCET4AAEBCET4AAEBCET4AAEBCET4AAEBCET4AAEBCET4AAEBCET4AAIAk0v8Hvfq6vNdXIYkAAAAASUVORK5CYII="
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最终拟合的权重 w: 10.144980430603027\n",
      "最终拟合的权重 b: 1.5215063095092773\n"
     ]
    }
   ],
   "execution_count": 50,
   "source": [
    "# 初始化模型参数 w 和 b\n",
    "w = torch.nn.Parameter(torch.tensor(0.1, dtype=torch.float32), requires_grad=True)\n",
    "b = torch.nn.Parameter(torch.tensor(0.1, dtype=torch.float32), requires_grad=True)\n",
    "\n",
    "# 定义优化器 (SGD - 随机梯度下降)\n",
    "optimizer = torch.optim.SGD([w, b], lr=0.1)  # 可适当提高学习率\n",
    "\n",
    "criterion = torch.nn.MSELoss()\n",
    "\n",
    "# 训练循环\n",
    "epochs = 200\n",
    "for epoch in range(epochs):\n",
    "    for x_batch, y_batch in dataloader:\n",
    "        # 前向传播: 批量预测\n",
    "        y_predict = w * x_batch + b\n",
    "\n",
    "        # 损失函数: 均方误差（MSE）\n",
    "        # loss = ((y_predict - y_batch) ** 2).mean()  # 对 batch 中的损失取平均\n",
    "        loss = criterion(y_predict, y_batch)\n",
    "\n",
    "        # 反向传播和优化\n",
    "        loss.backward()  # 计算当前 batch 下 w 和 b 的梯度\n",
    "        optimizer.step()  # 更新参数\n",
    "        optimizer.zero_grad()  # 清除上一次的梯度\n",
    "\n",
    "# 最终预测结果 一行就是一个样本的预测结果，所以进行行转列，从而变成一个数组\n",
    "final_prediction = (w.data.item() * x_tensor + b.data.item())\n",
    "\n",
    "# 绘图\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, final_prediction.numpy(), color='r')\n",
    "plt.show()\n",
    "\n",
    "# 输出最终的权重值\n",
    "print(f'最终拟合的权重 w: {w.data.item()}')\n",
    "print(f'最终拟合的权重 b: {b.data.item()}')\n"
   ],
   "id": "bbb055a61ac981d"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
